Open In Colab

LICENSING NOTICE¶

Note that all users who use Vital DB, an open biosignal dataset, must agree to the Data Use Agreement below. If you do not agree, please close this window. The Data Use Agreement is available here: https://vitaldb.net/dataset/#h.vcpgs1yemdb5

This is the development version of the project code¶

For the Project Draft submission see the DL4H_Team_24_Project_Draft.ipynb notebook in the project repository.

Project repository¶

The project repository can be found at: https://github.com/abarrie2/cs598-dlh-project

Introduction¶

This project aims to reproduce findings from the paper titled "Predicting intraoperative hypotension using deep learning with waveforms of arterial blood pressure, electroencephalogram, and electrocardiogram: Retrospective study" by Jo Y-Y et al. (2022) [1]. This study introduces a deep learning model that predicts intraoperative hypotension (IOH) events before they occur, utilizing a combination of arterial blood pressure (ABP), electroencephalogram (EEG), and electrocardiogram (ECG) signals.

Background of the Problem¶

Intraoperative hypotension (IOH) is a common and significant surgical complication defined by a mean arterial pressure drop below 65 mmHg. It is associated with increased risks of myocardial infarction, acute kidney injury, and heightened postoperative mortality. Effective prediction and timely intervention can substantially enhance patient outcomes.

Evolution of IOH Prediction¶

Initial attempts to predict IOH primarily used arterial blood pressure (ABP) waveforms. A foundational study by Hatib F et al. (2018) titled "Machine-learning Algorithm to Predict Hypotension Based on High-fidelity Arterial Pressure Waveform Analysis" [2] showed that machine learning could forecast IOH events using ABP with reasonable accuracy. This finding spurred further research into utilizing various physiological signals for IOH prediction.

Subsequent advancements included the development of the Acumen™ hypotension prediction index, which was studied in "AcumenTM hypotension prediction index guidance for prevention and treatment of hypotension in noncardiac surgery: a prospective, single-arm, multicenter trial" by Bao X et al. (2024) [3]. This trial integrated a hypotension prediction index into blood pressure monitoring equipment, demonstrating its effectiveness in reducing the number and duration of IOH events during surgeries. Further study is needed to determine whether this resultant reduction in IOH events transalates into improved postoperative patient outcomes.

Current Study¶

Building on these advancements, the paper by Jo Y-Y et al. (2022) proposes a deep learning approach that enhances prediction accuracy by incorporating EEG and ECG signals along with ABP. This multi-modal method, evaluated over prediction windows of 3, 5, 10, and 15 minutes, aims to provide a comprehensive physiological profile that could predict IOH more accurately and earlier. Their results indicate that the combination of ABP and EEG significantly improves performance metrics such as AUROC and AUPRC, outperforming models that use fewer signals or different combinations.

Our project seeks to reproduce and verify Jo Y-Y et al.'s results to assess whether this integrated approach can indeed improve IOH prediction accuracy, thereby potentially enhancing surgical safety and patient outcomes.

Scope of Reproducibility:¶

The original paper investigated the following hypotheses:

  1. Hypothesis 1: A model using ABP and ECG will outperform a model using ABP alone in predicting IOH.
  2. Hypothesis 2: A model using ABP and EEG will outperform a model using ABP alone in predicting IOH.
  3. Hypothesis 3: A model using ABP, EEG, and ECG will outperform a model using ABP alone in predicting IOH.

Results were compared using AUROC and AUPRC scores. Based on the results described in the original paper, we expect that Hypothesis 2 will be confirmed, and that Hypotheses 1 and 3 will not be confirmed.

In order to perform the corresponding experiments, we will implement a CNN-based model that can be configured to train and infer using the following four model variations:

  1. ABP data alone
  2. ABP and ECG data
  3. ABP and EEG data
  4. ABP, ECG, and EEG data

We will measure the performance of these configurations using the same AUROC and AUPRC metrics as used in the original paper. To test hypothesis 1 we will compare the AUROC and AUPRC measures between model variation 1 and model variation 2. To test hypothesis 2 we will compare the AUROC and AUPRC measures between model variation 1 and model variation 3. To test hypothesis 3 we will compare the AUROC and AUPRC measures between model variation 1 and model variation 4. For all of the above measures and experiment combinations, we will operate multiple experiments where the time-to-IOH event prediction will use the following prediction windows:

  1. 3 minutes before event
  2. 5 minutes before event
  3. 10 minutes before event
  4. 15 minutes before event

In the event that we are compute-bound, we will prioritize the 3-minute prediction window experiments as they are the most relevant to the original paper's findings.

The predictive power of ABP, ECG and ABP + ECG models at 3-, 5-, 10- and 15-minute prediction windows: Predictive power of ABP, ECG and ABP + ECG models at 3-, 5-, 10- and 15-minute prediction windows

Modifications made for demo mode¶

In order to demonstrate the functioning of the code in a short (ie, <8 minute limit) the following options and modifications were used:

  1. MAX_CASES was set to 20. The total number of cases to be used in the full training set is 3296, but the smaller numbers allows demonstration of each section of the pipeline.
  2. vitaldb_cache is prepopulated in Google Colab. The cache file is approx. 800MB and contains the raw and mini-fied copies of the source dataset and is downloaded from Google Drive. This is much faster than using the vitaldb API, but is again only a fraction of the data. The full dataset can be downloaded with the API or prepopulated by following the instructions in the "Bulk Data Download" section below.
  3. max_epochs is set to 6. With the small dataset, training is fast and shows the decreasing training and validation losses. In the full model run, max_epochs will be set to 100. In both cases early stopping is enabled and will stop training if the validation losses stop decreasing for five consecutive epochs.
  4. Only the "ABP + EEG" combination will be run. In the final report, additional combinations will be run, as discussed later.
  5. Only the 3-minute prediction window will be run. In the final report, additional prediction windows (5, 10 and 15 minutes) will be run, as discussed later.
  6. No ablations are run in the demo. These will be completed for the final report.

Methodology¶

Methodology from Final Rubrik¶

  • Environment
    • Python version
    • Dependencies/packages needed
  • Data
    • Data download instruction
    • Data descriptions with helpful charts and visualizations
    • Preprocessing code + command
  • Model
    • Citation to the original paper
    • Link to the original paper’s repo (if applicable)
    • Model descriptions
    • Implementation code
    • Pretrained model (if applicable)
  • Training
    • Hyperparams
      • Report at least 3 types of hyperparameters such as learning rate, batch size, hidden size, dropout
    • Computational requirements
      • Report at least 3 types of requirements such as type of hardware, average runtime for each epoch, total number of trials, GPU hrs used, # training epochs
      • Training code
  • Evaluation
    • Metrics descriptions
    • Evaluation code

The methodology section is composed of the following subsections: Environment, Data and Model.

  • Environment: This section describes the setup of the environment, including the installation of necessary libraries and the configuration of the runtime environment.
  • Data: This section describes the dataset used in the study, including its collection and preprocessing.
    • Data Collection: This section describes the process of downloading the dataset from VitalDB and populating the local data cache.
    • Data Preprocessing: This section describes the preprocessing steps applied to the dataset, including data selection, data cleaning, and feature extraction.
  • Model: This section describes the deep learning model used in the study, including its implementation, training, and evaluation.
    • Model Implementation: This section describes the implementation of the deep learning model, including the architecture, loss function, and optimization algorithm.
    • Model Training: This section describes the training process, including the training loop, hyperparameters, and training strategy.
    • Model Evaluation: This section describes the evaluation process, including the metrics used, the evaluation strategy, and the results obtained.

Environment¶

Create environment¶

The environment setup differs based on whether you are running the code on a local machine or on Google Colab. The following sections provide instructions for setting up the environment in each case.

Local machine¶

Create conda environment for the project using the environment.yml file:

conda env create --prefix .envs/dlh-team24 -f environment.yml

Activate the environment with:

conda activate .envs/dlh-team24

Google Colab¶

The following code snippet installs the required packages and downloads the necessary files in a Google Colab environment:

In [1]:
# Google Colab environments have a `/content` directory. Use this as a proxy for running Colab-only code
COLAB_ENV = "google.colab" in str(get_ipython())
if COLAB_ENV:
    #install vitaldb
    %pip install vitaldb

    # Executing in Colab therefore download cached preprocessed data.
    # TODO: Integrate this with the setup local cache data section below.
    # Check for file existence before overwriting.
    import gdown
    gdown.download(id="15b5Nfhgj3McSO2GmkVUKkhSSxQXX14hJ", output="vitaldb_cache.tgz")
    !tar -zxf vitaldb_cache.tgz

    # Download sqi_filter.csv from github repo
    !wget https://raw.githubusercontent.com/abarrie2/cs598-dlh-project/main/sqi_filter.csv

All other required packages are already installed in the Google Colab environment.

Load environment¶

In [2]:
# Import packages
import os
import random
import copy
from collections import defaultdict

from timeit import default_timer as timer

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, roc_auc_score, precision_recall_curve, auc, confusion_matrix
from sklearn.metrics import RocCurveDisplay, PrecisionRecallDisplay, average_precision_score
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
import torch
from torch.utils.data import Dataset
import vitaldb
import h5py

import torch.nn as nn
import torch.nn.functional as F
from tqdm import tqdm
from datetime import datetime

Set random seeds to generate consistent results:

In [3]:
RANDOM_SEED = 42
random.seed(RANDOM_SEED)
np.random.seed(RANDOM_SEED)
torch.manual_seed(RANDOM_SEED)
if torch.cuda.is_available():
    torch.cuda.manual_seed(RANDOM_SEED)
    torch.cuda.manual_seed_all(RANDOM_SEED)
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False
os.environ["PYTHONHASHSEED"] = str(RANDOM_SEED)

Set device to GPU or MPS if available

In [4]:
device = torch.device("cuda" if torch.cuda.is_available() else "mps" if (torch.backends.mps.is_available() and torch.backends.mps.is_built()) else "cpu")
print(f"Using device: {device}")
Using device: mps

Data¶

Data Description¶

Source¶

Data for this project is sourced from the open biosignal VitalDB dataset as described in "VitalDB, a high-fidelity multi-parameter vital signs database in surgical patients" by Lee H-C et al. (2022) [4], which contains perioperative vital signs and numerical data from 6,388 cases of non-cardiac (general, thoracic, urological, and gynecological) surgery patients who underwent routine or emergency surgery at Seoul National University Hospital between 2016 and 2017. The dataset includes ABP, ECG, and EEG signals, as well as other physiological data. The dataset is available through an API and Python library, and at PhysioNet: https://physionet.org/content/vitaldb/1.0.0/

Statistics¶

Characteristics of the dataset: | Characteristic | Value | Details | |-----------------------|-----------------------------|------------------------| | Total number of cases | 6,388 | | | Sex (male) | 3,243 (50.8%) | | | Age (years) | 59 | Range: 48-68 | | Height (cm) | 162 | Range: 156-169 | | Weight (kg) | 61 | Range: 53-69 | | Tram-Rac 4A tracks | 6,355 (99.5%) | Sampling rate: 500Hz | | BIS Vista tracks | 5,566 (87.1%) | Sampling rate: 128Hz | | Case duration (min) | 189 | Range: 27-1041 |

Labels are only known after processing the data. In the original paper, there were an average of 1.6 IOH events per case and 5.7 non-events per case so we expect approximately 10,221 IOH events and 364,116 non-events in the dataset.

Data Processing¶

Data will be processed as follows:

  1. Load the dataset from VitalDB, or from a local cache if previously downloaded.
  2. Apply the inclusion and exclusion selection criteria to filter the dataset according to surgery metadata.
  3. Generate a minified dataset by discarding all tracks except ABP, ECG, and EEG.
  4. Preprocess the data by applying band-pass and z-score normalization to the ECG and EEG signals, and filtering out ABP signals below a Signal Quality Index (SQI) threshold.
  5. Generate event and non-event samples by extracting 60-second segments around IOH events and non-events.
  6. Split the dataset into training, validation, and test sets with a 6:1:3 ratio, ensuring that samples from a single case are not split across different sets to avoid data leakage.

Set Up Local Data Caches¶

VitalDB data is static, so local copies can be stored and reused to avoid expensive downloads and to speed up data processing.

The default directory defined below is in the project .gitignore file. If this is modified, the new directory should also be added to the project .gitignore.

In [5]:
VITALDB_CACHE = './vitaldb_cache'
VITAL_ALL = f"{VITALDB_CACHE}/vital_all"
VITAL_MINI = f"{VITALDB_CACHE}/vital_mini"
VITAL_METADATA = f"{VITALDB_CACHE}/metadata"
VITAL_MODELS = f"{VITALDB_CACHE}/models"
VITAL_PREPROCESS_SCRATCH = f"{VITALDB_CACHE}/data_scratch"
VITAL_EXTRACTED_SEGMENTS = f"{VITALDB_CACHE}/segments"
In [6]:
TRACK_CACHE = None
SEGMENT_CACHE = None

# when USE_MEMORY_CACHING is enabled, track data will be persisted in an in-memory cache. Not useful once we have already pre-extracted all event segments
# DON'T USE: Stores items in memory that are later not used. Causes OOM on segment extraction.
USE_MEMORY_CACHING = False

# When RESET_CACHE is set to True, it will ensure the TRACK_CACHE is disposed and recreated when we do dataset initialization.
# Use as a shortcut to wiping cache rather than restarting kernel
RESET_CACHE = False

PREDICTION_WINDOW = 3
#PREDICTION_WINDOW = 'ALL'

ALL_PREDICTION_WINDOWS = [3, 5, 10, 15]

# Maximum number of cases of interest for which to download data.
# Set to a small value (ex: 20) for demo purposes, else set to None to disable and download and process all.
MAX_CASES = None
#MAX_CASES = 300

# Preloading Cases: when true, all matched cases will have the _mini tracks extracted and put into in-mem dict
PRELOADING_CASES = False
PRELOADING_SEGMENTS = True
# Perform Data Preprocessing: do we want to take the raw vital file and extract segments of interest for training?
PERFORM_DATA_PREPROCESSING = False
In [7]:
if not os.path.exists(VITALDB_CACHE):
  os.mkdir(VITALDB_CACHE)
if not os.path.exists(VITAL_ALL):
  os.mkdir(VITAL_ALL)
if not os.path.exists(VITAL_MINI):
  os.mkdir(VITAL_MINI)
if not os.path.exists(VITAL_METADATA):
  os.mkdir(VITAL_METADATA)
if not os.path.exists(VITAL_MODELS):
  os.mkdir(VITAL_MODELS)
if not os.path.exists(VITAL_PREPROCESS_SCRATCH):
  os.mkdir(VITAL_PREPROCESS_SCRATCH)
if not os.path.exists(VITAL_EXTRACTED_SEGMENTS):
  os.mkdir(VITAL_EXTRACTED_SEGMENTS)

print(os.listdir(VITALDB_CACHE))
['segments_filter_neg', 'segments_bak', '.DS_Store', 'vital_mini_bak_0501', 'vital_all', 'models_all_cases_baseline', 'models', 'docs', 'vital_mini.tar', 'data_scratch', 'segments_bak_0501', 'osfs', 'vital_mini', 'segments_filter_none', 'metadata', 'segments', 'models_old']

Bulk Data Download¶

This step is not required, but will significantly speed up downstream processing and avoid a high volume of API requests to the VitalDB web site.

The cache population code checks if the .vital files are locally available, and can be populated by calling the vitaldb API or by manually prepopulating the cache (recommended)

  • Manually downloaded the dataset from the following site: https://physionet.org/content/vitaldb/1.0.0/
    • Download the zip file in a browser, or
    • Use wget -r -N -c -np https://physionet.org/files/vitaldb/1.0.0/ to download the files in a terminal
  • Move the contents of vital_files into the ${VITAL_ALL} directory.
In [8]:
# Returns the Pandas DataFrame for the specified dataset.
#   One of 'cases', 'labs', or 'trks'
# If the file exists locally, create and return the DataFrame.
# Else, download and cache the csv first, then return the DataFrame.
def vitaldb_dataframe_loader(dataset_name):
    if dataset_name not in ['cases', 'labs', 'trks']:
        raise ValueError(f'Invalid dataset name: {dataset_name}')
    file_path = f'{VITAL_METADATA}/{dataset_name}.csv'
    if os.path.isfile(file_path):
        print(f'{dataset_name}.csv exists locally.')
        df = pd.read_csv(file_path)
        return df
    else:
        print(f'downloading {dataset_name} and storing in the local cache for future reuse.')
        df = pd.read_csv(f'https://api.vitaldb.net/{dataset_name}')
        df.to_csv(file_path, index=False)
        return df

Exploratory Data Analysis¶

Cases¶

In [9]:
cases = vitaldb_dataframe_loader('cases')
cases = cases.set_index('caseid')
cases.shape
cases.csv exists locally.
Out[9]:
(6388, 73)
In [10]:
cases.index.nunique()
Out[10]:
6388
In [11]:
cases.head()
Out[11]:
subjectid casestart caseend anestart aneend opstart opend adm dis icu_days ... intraop_colloid intraop_ppf intraop_mdz intraop_ftn intraop_rocu intraop_vecu intraop_eph intraop_phe intraop_epi intraop_ca
caseid
1 5955 0 11542 -552 10848.0 1668 10368 -236220 627780 0 ... 0 120 0.0 100 70 0 10 0 0 0
2 2487 0 15741 -1039 14921.0 1721 14621 -221160 1506840 0 ... 0 150 0.0 0 100 0 20 0 0 0
3 2861 0 4394 -590 4210.0 1090 3010 -218640 40560 0 ... 0 0 0.0 0 50 0 0 0 0 0
4 1903 0 20990 -778 20222.0 2522 17822 -201120 576480 1 ... 0 80 0.0 100 100 0 50 0 0 0
5 4416 0 21531 -1009 22391.0 2591 20291 -67560 3734040 13 ... 0 0 0.0 0 160 0 10 900 0 2100

5 rows × 73 columns

In [12]:
cases['sex'].value_counts()
Out[12]:
sex
M    3243
F    3145
Name: count, dtype: int64

Tracks¶

In [13]:
trks = vitaldb_dataframe_loader('trks')
trks = trks.set_index('caseid')
trks.shape
trks.csv exists locally.
Out[13]:
(486449, 2)
In [14]:
trks.index.nunique()
Out[14]:
6388
In [15]:
trks.groupby('caseid')[['tid']].count().plot();
In [16]:
trks.groupby('caseid')[['tid']].count().hist();
In [17]:
trks.groupby('tname').count().sort_values(by='tid', ascending=False)
Out[17]:
tid
tname
Solar8000/HR 6387
Solar8000/PLETH_SPO2 6386
Solar8000/PLETH_HR 6386
Primus/CO2 6362
Primus/PAMB_MBAR 6361
... ...
Orchestra/AMD_VOL 1
Solar8000/ST_V5 1
Orchestra/NPS_VOL 1
Orchestra/AMD_RATE 1
Orchestra/VEC_VOL 1

196 rows × 1 columns

Parameters of Interest¶

Hemodynamic Parameters Reference¶

https://vitaldb.net/dataset/?query=overview#h.f7d712ycdpk2

SNUADC/ART

arterial blood pressure waveform

Parameter, Description, Type/Hz, Unit

SNUADC/ART, Arterial pressure wave, W/500, mmHg

In [18]:
trks[trks['tname'].str.contains('SNUADC/ART')].shape
Out[18]:
(3645, 2)

SNUADC/ECG_II

electrocardiogram waveform

Parameter, Description, Type/Hz, Unit

SNUADC/ECG_II, ECG lead II wave, W/500, mV

In [19]:
trks[trks['tname'].str.contains('SNUADC/ECG_II')].shape
Out[19]:
(6355, 2)

BIS/EEG1_WAV

electroencephalogram waveform

Parameter, Description, Type/Hz, Unit

BIS/EEG1_WAV, EEG wave from channel 1, W/128, uV

In [20]:
trks[trks['tname'].str.contains('BIS/EEG1_WAV')].shape
Out[20]:
(5871, 2)

Cases of Interest¶

These are the subset of case ids for which modelling and analysis will be performed based upon inclusion criteria and waveform data availability.

In [21]:
# TRACK NAMES is used for metadata analysis via API
TRACK_NAMES = ['SNUADC/ART', 'SNUADC/ECG_II', 'BIS/EEG1_WAV']
TRACK_SRATES = [500, 500, 128]
# EXTRACTION TRACK NAMES adds the EVENT track which is only used when doing actual file i/o
EXTRACTION_TRACK_NAMES = ['SNUADC/ART', 'SNUADC/ECG_II', 'BIS/EEG1_WAV', 'EVENT']
EXTRACTION_TRACK_SRATES = [500, 500, 128, 1]
In [22]:
# As in the paper, select cases which meet the following criteria:
#
# For patients, the inclusion criteria were as follows:
# (1) adults (age >= 18)
# (2) administered general anaesthesia
# (3) undergone non-cardiac surgery. 
#
# For waveform data, the inclusion criteria were as follows:
# (1) no missing monitoring for ABP, ECG, and EEG waveforms
# (2) no cases containing false events or non-events due to poor signal quality
#     (checked in second stage of data preprocessing)

# Adult
inclusion_1 = cases.loc[cases['age'] >= 18].index
print(f'{len(cases)-len(inclusion_1)} cases excluded, {len(inclusion_1)} remaining due to age criteria')

# General Anesthesia
inclusion_2 = cases.loc[cases['ane_type'] == 'General'].index
print(f'{len(cases)-len(inclusion_2)} cases excluded, {len(inclusion_2)} remaining due to anesthesia criteria')

# Non-cardiac surgery
inclusion_3 = cases.loc[
    ~cases['opname'].str.contains("cardiac", case=False)
    & ~cases['opname'].str.contains("aneurysmal", case=False)
].index
print(f'{len(cases)-len(inclusion_3)} cases excluded, {len(inclusion_3)} remaining due to non-cardiac surgery criteria')

# ABP, ECG, EEG waveforms
inclusion_4 = trks.loc[trks['tname'].isin(TRACK_NAMES)].index.value_counts()
inclusion_4 = inclusion_4[inclusion_4 == len(TRACK_NAMES)].index
print(f'{len(cases)-len(inclusion_4)} cases excluded, {len(inclusion_4)} remaining due to missing waveform data')

# SQI filter
# NOTE: this depends on a sqi_filter.csv generated by external processing
inclusion_5 = pd.read_csv('sqi_filter.csv', header=None, names=['caseid','sqi']).set_index('caseid').index
print(f'{len(cases)-len(inclusion_5)} cases excluded, {len(inclusion_5)} remaining due to SQI threshold not being met')

# Only include cases with known good waveforms.
exclusion_6 = pd.read_csv('malformed_tracks_filter.csv', header=None, names=['caseid']).set_index('caseid').index
inclusion_6 = cases.index.difference(exclusion_6)
print(f'{len(cases)-len(inclusion_6)} cases excluded, {len(inclusion_6)} remaining due to malformed waveforms')

cases_of_interest_idx = inclusion_1 \
    .intersection(inclusion_2) \
    .intersection(inclusion_3) \
    .intersection(inclusion_4) \
    .intersection(inclusion_5) \
    .intersection(inclusion_6)

cases_of_interest = cases.loc[cases_of_interest_idx]

print()
print(f'{cases_of_interest_idx.shape[0]} out of {cases.shape[0]} total cases remaining after exclusions applied')

# Trim cases of interest to MAX_CASES
if MAX_CASES:
    cases_of_interest_idx = cases_of_interest_idx[:MAX_CASES]
print(f'{cases_of_interest_idx.shape[0]} cases of interest selected')
57 cases excluded, 6331 remaining due to age criteria
345 cases excluded, 6043 remaining due to anesthesia criteria
14 cases excluded, 6374 remaining due to non-cardiac surgery criteria
3019 cases excluded, 3369 remaining due to missing waveform data
0 cases excluded, 6388 remaining due to SQI threshold not being met
186 cases excluded, 6202 remaining due to malformed waveforms

3110 out of 6388 total cases remaining after exclusions applied
3110 cases of interest selected
In [23]:
cases_of_interest.head(n=5)
Out[23]:
subjectid casestart caseend anestart aneend opstart opend adm dis icu_days ... intraop_colloid intraop_ppf intraop_mdz intraop_ftn intraop_rocu intraop_vecu intraop_eph intraop_phe intraop_epi intraop_ca
caseid
1 5955 0 11542 -552 10848.0 1668 10368 -236220 627780 0 ... 0 120 0.0 100 70 0 10 0 0 0
4 1903 0 20990 -778 20222.0 2522 17822 -201120 576480 1 ... 0 80 0.0 100 100 0 50 0 0 0
7 5124 0 15770 477 14817.0 3177 14577 -154320 623280 3 ... 0 0 0.0 0 120 0 0 0 0 0
10 2175 0 20992 -1743 21057.0 2457 19857 -220740 3580860 1 ... 0 90 0.0 0 110 0 20 500 0 600
12 491 0 31203 -220 31460.0 5360 30860 -208500 1519500 4 ... 200 100 0.0 100 70 0 20 0 0 3300

5 rows × 73 columns

Tracks of Interest¶

These are the subset of tracks (waveforms) for the cases of interest identified above.

In [24]:
# A single case maps to one or more waveform tracks. Select only the tracks required for analysis.
trks_of_interest = trks.loc[cases_of_interest_idx][trks.loc[cases_of_interest_idx]['tname'].isin(TRACK_NAMES)]
trks_of_interest.shape
Out[24]:
(9330, 2)
In [25]:
trks_of_interest.head(n=5)
Out[25]:
tname tid
caseid
1 BIS/EEG1_WAV 0aa685df768489a18a5e9f53af0d83bf60890c73
1 SNUADC/ART 724cdd7184d7886b8f7de091c5b135bd01949959
1 SNUADC/ECG_II 8c9161aaae8cb578e2aa7b60f44234d98d2b3344
4 BIS/EEG1_WAV 1b4c2379be3397a79d3787dd810190150dc53f27
4 SNUADC/ART e28777c4706fe3a5e714bf2d91821d22d782d802
In [26]:
trks_of_interest_idx = trks_of_interest.set_index('tid').index
trks_of_interest_idx.shape
Out[26]:
(9330,)

Build Tracks Cache for Local Processing¶

Tracks data are large and therefore expensive to download every time used. By default, the .vital file format stores all tracks for each case internally. Since only select tracks per case are required, each .vital file can be further reduced by discarding the unused tracks.

In [27]:
# Ensure the full vital file dataset is available for cases of interest.
count_downloaded = 0
count_present = 0

#for i, idx in enumerate(cases.index):
for idx in cases_of_interest_idx:
    full_path = f'{VITAL_ALL}/{idx:04d}.vital'
    if not os.path.isfile(full_path):
        print(f'Missing vital file: {full_path}')
        # Download and save the file.
        vf = vitaldb.VitalFile(idx)
        vf.to_vital(full_path)
        count_downloaded += 1
    else:
        count_present += 1

print()
print(f'Count of cases of interest:           {cases_of_interest_idx.shape[0]}')
print(f'Count of vital files downloaded:      {count_downloaded}')
print(f'Count of vital files already present: {count_present}')
Count of cases of interest:           3110
Count of vital files downloaded:      0
Count of vital files already present: 3110

Validate Mini Files¶

In [28]:
# Convert vital files to "mini" versions including only the subset of tracks defined in TRACK_NAMES above.
# Only perform conversion for the cases of interest.
# NOTE: If this cell is interrupted, it can be restarted and will continue where it left off.
count_minified = 0
count_present = 0
count_missing_tracks = 0
count_not_fixable = 0

# If set to true, local mini files are checked for all tracks even if the mini file is already present.
FORCE_VALIDATE = True

for idx in cases_of_interest_idx:
    full_path = f'{VITAL_ALL}/{idx:04d}.vital'
    mini_path = f'{VITAL_MINI}/{idx:04d}_mini.vital'

    if FORCE_VALIDATE or not os.path.isfile(mini_path):
        print(f'Creating mini vital file: {idx}')
        vf = vitaldb.VitalFile(full_path, EXTRACTION_TRACK_NAMES)
        
        if len(vf.get_track_names()) != 4:
            print(f'Missing track in vital file: {idx}, {set(EXTRACTION_TRACK_NAMES).difference(set(vf.get_track_names()))}')
            count_missing_tracks += 1
            
            # Attempt to download from VitalDB directly and see if missing tracks are present.
            vf = vitaldb.VitalFile(idx, EXTRACTION_TRACK_NAMES)
            
            if len(vf.get_track_names()) != 4:
                print(f'Unable to fix missing tracks: {idx}')
                count_not_fixable += 1
                continue
                
            if vf.get_track_samples(EXTRACTION_TRACK_NAMES[0], 1/EXTRACTION_TRACK_SRATES[0]).shape[0] == 0:
                print(f'Empty track: {idx}, {EXTRACTION_TRACK_NAMES[0]}')
                count_not_fixable += 1
                continue
                
            if vf.get_track_samples(EXTRACTION_TRACK_NAMES[1], 1/EXTRACTION_TRACK_SRATES[1]).shape[0] == 0:
                print(f'Empty track: {idx}, {EXTRACTION_TRACK_NAMES[1]}')
                count_not_fixable += 1
                continue
                
            if vf.get_track_samples(EXTRACTION_TRACK_NAMES[2], 1/EXTRACTION_TRACK_SRATES[2]).shape[0] == 0:
                print(f'Empty track: {idx}, {EXTRACTION_TRACK_NAMES[2]}')
                count_not_fixable += 1
                continue

            if vf.get_track_samples(EXTRACTION_TRACK_NAMES[3], 1/EXTRACTION_TRACK_SRATES[3]).shape[0] == 0:
                print(f'Empty track: {idx}, {EXTRACTION_TRACK_NAMES[3]}')
                count_not_fixable += 1
                continue

        vf.to_vital(mini_path)
        count_minified += 1
    else:
        count_present += 1

print()
print(f'Count of cases of interest:           {cases_of_interest_idx.shape[0]}')
print(f'Count of vital files minified:        {count_minified}')
print(f'Count of vital files already present: {count_present}')
print(f'Count of vital files missing tracks:  {count_missing_tracks}')
print(f'Count of vital files not fixable:     {count_not_fixable}')
Creating mini vital file: 1
Creating mini vital file: 4
Creating mini vital file: 7
Creating mini vital file: 10
Creating mini vital file: 12
Creating mini vital file: 13
Creating mini vital file: 16
Creating mini vital file: 19
Creating mini vital file: 20
Creating mini vital file: 22
Creating mini vital file: 24
Creating mini vital file: 25
Creating mini vital file: 26
Creating mini vital file: 27
Creating mini vital file: 29
Creating mini vital file: 31
Creating mini vital file: 34
Creating mini vital file: 38
Creating mini vital file: 43
Creating mini vital file: 44
Creating mini vital file: 46
Creating mini vital file: 49
Creating mini vital file: 50
Creating mini vital file: 52
Creating mini vital file: 53
Creating mini vital file: 55
Creating mini vital file: 58
Creating mini vital file: 59
Creating mini vital file: 60
Creating mini vital file: 61
Creating mini vital file: 64
Creating mini vital file: 65
Creating mini vital file: 66
Creating mini vital file: 67
Creating mini vital file: 68
Creating mini vital file: 69
Creating mini vital file: 70
Creating mini vital file: 74
Creating mini vital file: 75
Creating mini vital file: 77
Creating mini vital file: 79
Creating mini vital file: 83
Creating mini vital file: 84
Creating mini vital file: 87
Creating mini vital file: 89
Creating mini vital file: 92
Creating mini vital file: 93
Creating mini vital file: 94
Creating mini vital file: 96
Creating mini vital file: 97
Creating mini vital file: 98
Creating mini vital file: 101
Creating mini vital file: 104
Creating mini vital file: 105
Creating mini vital file: 108
Creating mini vital file: 110
Creating mini vital file: 111
Creating mini vital file: 112
Creating mini vital file: 114
Creating mini vital file: 116
Creating mini vital file: 117
Creating mini vital file: 118
Creating mini vital file: 119
Creating mini vital file: 124
Creating mini vital file: 125
Creating mini vital file: 126
Creating mini vital file: 128
Creating mini vital file: 130
Creating mini vital file: 132
Creating mini vital file: 135
Creating mini vital file: 136
Creating mini vital file: 137
Creating mini vital file: 138
Creating mini vital file: 139
Creating mini vital file: 140
Creating mini vital file: 142
Creating mini vital file: 143
Creating mini vital file: 145
Creating mini vital file: 146
Creating mini vital file: 148
Creating mini vital file: 149
Creating mini vital file: 152
Creating mini vital file: 153
Creating mini vital file: 156
Creating mini vital file: 161
Creating mini vital file: 163
Creating mini vital file: 166
Creating mini vital file: 167
Creating mini vital file: 172
Creating mini vital file: 175
Creating mini vital file: 177
Creating mini vital file: 178
Creating mini vital file: 181
Creating mini vital file: 183
Creating mini vital file: 184
Creating mini vital file: 186
Creating mini vital file: 190
Creating mini vital file: 191
Creating mini vital file: 195
Creating mini vital file: 197
Creating mini vital file: 198
Creating mini vital file: 199
Creating mini vital file: 200
Creating mini vital file: 202
Creating mini vital file: 203
Creating mini vital file: 206
Creating mini vital file: 208
Creating mini vital file: 210
Creating mini vital file: 218
Creating mini vital file: 221
Creating mini vital file: 222
Creating mini vital file: 229
Creating mini vital file: 232
Creating mini vital file: 233
Creating mini vital file: 234
Creating mini vital file: 236
Creating mini vital file: 237
Creating mini vital file: 239
Creating mini vital file: 241
Creating mini vital file: 244
Creating mini vital file: 247
Creating mini vital file: 250
Creating mini vital file: 251
Creating mini vital file: 252
Creating mini vital file: 256
Creating mini vital file: 258
Creating mini vital file: 261
Creating mini vital file: 263
Creating mini vital file: 266
Creating mini vital file: 268
Creating mini vital file: 269
Creating mini vital file: 270
Creating mini vital file: 279
Creating mini vital file: 281
Creating mini vital file: 282
Creating mini vital file: 283
Creating mini vital file: 286
Creating mini vital file: 287
Creating mini vital file: 293
Creating mini vital file: 295
Creating mini vital file: 296
Creating mini vital file: 297
Creating mini vital file: 300
Creating mini vital file: 303
Creating mini vital file: 304
Creating mini vital file: 306
Creating mini vital file: 308
Creating mini vital file: 309
Creating mini vital file: 312
Creating mini vital file: 316
Creating mini vital file: 318
Creating mini vital file: 319
Creating mini vital file: 321
Creating mini vital file: 323
Creating mini vital file: 327
Creating mini vital file: 330
Creating mini vital file: 337
Creating mini vital file: 338
Creating mini vital file: 342
Creating mini vital file: 343
Creating mini vital file: 345
Creating mini vital file: 347
Creating mini vital file: 348
Creating mini vital file: 349
Creating mini vital file: 353
Creating mini vital file: 354
Creating mini vital file: 355
Creating mini vital file: 357
Creating mini vital file: 358
Creating mini vital file: 359
Creating mini vital file: 362
Creating mini vital file: 363
Creating mini vital file: 367
Creating mini vital file: 369
Creating mini vital file: 370
Creating mini vital file: 371
Creating mini vital file: 375
Creating mini vital file: 380
Creating mini vital file: 382
Creating mini vital file: 383
Creating mini vital file: 384
Creating mini vital file: 387
Creating mini vital file: 388
Creating mini vital file: 390
Creating mini vital file: 397
Creating mini vital file: 398
Creating mini vital file: 402
Creating mini vital file: 404
Creating mini vital file: 405
Creating mini vital file: 406
Creating mini vital file: 408
Creating mini vital file: 409
Creating mini vital file: 413
Creating mini vital file: 415
Creating mini vital file: 416
Creating mini vital file: 417
Creating mini vital file: 418
Creating mini vital file: 419
Creating mini vital file: 425
Creating mini vital file: 427
Creating mini vital file: 431
Creating mini vital file: 435
Creating mini vital file: 439
Creating mini vital file: 440
Creating mini vital file: 441
Creating mini vital file: 442
Creating mini vital file: 445
Creating mini vital file: 447
Creating mini vital file: 448
Creating mini vital file: 449
Creating mini vital file: 451
Creating mini vital file: 452
Creating mini vital file: 455
Creating mini vital file: 458
Creating mini vital file: 462
Creating mini vital file: 466
Creating mini vital file: 469
Creating mini vital file: 472
Creating mini vital file: 474
Creating mini vital file: 476
Creating mini vital file: 478
Creating mini vital file: 481
Creating mini vital file: 484
Creating mini vital file: 485
Creating mini vital file: 486
Creating mini vital file: 488
Creating mini vital file: 490
Creating mini vital file: 492
Creating mini vital file: 495
Creating mini vital file: 499
Creating mini vital file: 505
Creating mini vital file: 512
Creating mini vital file: 513
Creating mini vital file: 516
Creating mini vital file: 520
Creating mini vital file: 521
Creating mini vital file: 526
Creating mini vital file: 527
Creating mini vital file: 530
Creating mini vital file: 531
Creating mini vital file: 535
Creating mini vital file: 536
Creating mini vital file: 537
Creating mini vital file: 541
Creating mini vital file: 543
Creating mini vital file: 544
Creating mini vital file: 545
Creating mini vital file: 547
Creating mini vital file: 550
Creating mini vital file: 551
Creating mini vital file: 553
Creating mini vital file: 559
Creating mini vital file: 560
Creating mini vital file: 561
Creating mini vital file: 562
Creating mini vital file: 563
Creating mini vital file: 564
Creating mini vital file: 566
Creating mini vital file: 567
Creating mini vital file: 568
Creating mini vital file: 570
Creating mini vital file: 573
Creating mini vital file: 576
Creating mini vital file: 577
Creating mini vital file: 579
Creating mini vital file: 582
Creating mini vital file: 584
Creating mini vital file: 585
Creating mini vital file: 587
Creating mini vital file: 590
Creating mini vital file: 593
Creating mini vital file: 594
Creating mini vital file: 599
Creating mini vital file: 611
Creating mini vital file: 612
Creating mini vital file: 616
Creating mini vital file: 617
Creating mini vital file: 620
Creating mini vital file: 621
Creating mini vital file: 622
Creating mini vital file: 624
Creating mini vital file: 627
Creating mini vital file: 628
Creating mini vital file: 629
Creating mini vital file: 631
Creating mini vital file: 634
Creating mini vital file: 636
Creating mini vital file: 637
Creating mini vital file: 641
Creating mini vital file: 644
Creating mini vital file: 645
Creating mini vital file: 648
Creating mini vital file: 649
Creating mini vital file: 650
Creating mini vital file: 652
Creating mini vital file: 655
Creating mini vital file: 657
Creating mini vital file: 659
Creating mini vital file: 660
Creating mini vital file: 663
Creating mini vital file: 665
Creating mini vital file: 666
Creating mini vital file: 667
Creating mini vital file: 671
Creating mini vital file: 672
Creating mini vital file: 676
Creating mini vital file: 679
Creating mini vital file: 680
Creating mini vital file: 683
Creating mini vital file: 684
Creating mini vital file: 685
Creating mini vital file: 687
Creating mini vital file: 689
Creating mini vital file: 691
Creating mini vital file: 697
Creating mini vital file: 698
Creating mini vital file: 699
Creating mini vital file: 702
Creating mini vital file: 703
Creating mini vital file: 706
Creating mini vital file: 711
Creating mini vital file: 716
Creating mini vital file: 719
Creating mini vital file: 721
Creating mini vital file: 722
Creating mini vital file: 724
Creating mini vital file: 725
Creating mini vital file: 726
Creating mini vital file: 728
Creating mini vital file: 729
Creating mini vital file: 730
Creating mini vital file: 733
Creating mini vital file: 734
Creating mini vital file: 737
Creating mini vital file: 739
Creating mini vital file: 740
Creating mini vital file: 742
Creating mini vital file: 744
Creating mini vital file: 745
Creating mini vital file: 746
Creating mini vital file: 747
Creating mini vital file: 748
Creating mini vital file: 749
Creating mini vital file: 750
Creating mini vital file: 751
Creating mini vital file: 752
Creating mini vital file: 753
Creating mini vital file: 755
Creating mini vital file: 756
Creating mini vital file: 757
Creating mini vital file: 758
Creating mini vital file: 761
Creating mini vital file: 762
Creating mini vital file: 763
Creating mini vital file: 764
Creating mini vital file: 765
Creating mini vital file: 767
Creating mini vital file: 768
Creating mini vital file: 770
Creating mini vital file: 772
Creating mini vital file: 773
Creating mini vital file: 774
Creating mini vital file: 775
Creating mini vital file: 776
Creating mini vital file: 777
Creating mini vital file: 779
Creating mini vital file: 781
Creating mini vital file: 783
Creating mini vital file: 788
Creating mini vital file: 792
Creating mini vital file: 793
Creating mini vital file: 794
Creating mini vital file: 795
Creating mini vital file: 797
Creating mini vital file: 800
Creating mini vital file: 802
Creating mini vital file: 807
Creating mini vital file: 808
Creating mini vital file: 810
Creating mini vital file: 812
Creating mini vital file: 813
Creating mini vital file: 814
Creating mini vital file: 815
Creating mini vital file: 816
Creating mini vital file: 818
Creating mini vital file: 819
Creating mini vital file: 822
Creating mini vital file: 825
Creating mini vital file: 827
Creating mini vital file: 830
Creating mini vital file: 831
Creating mini vital file: 833
Creating mini vital file: 835
Creating mini vital file: 841
Creating mini vital file: 843
Creating mini vital file: 846
Creating mini vital file: 847
Creating mini vital file: 848
Creating mini vital file: 851
Creating mini vital file: 852
Creating mini vital file: 853
Creating mini vital file: 855
Creating mini vital file: 859
Creating mini vital file: 860
Creating mini vital file: 864
Creating mini vital file: 865
Creating mini vital file: 866
Creating mini vital file: 868
Creating mini vital file: 869
Creating mini vital file: 870
Creating mini vital file: 871
Creating mini vital file: 872
Creating mini vital file: 876
Creating mini vital file: 879
Creating mini vital file: 880
Creating mini vital file: 881
Creating mini vital file: 883
Creating mini vital file: 885
Creating mini vital file: 886
Creating mini vital file: 887
Creating mini vital file: 890
Creating mini vital file: 892
Creating mini vital file: 894
Creating mini vital file: 898
Creating mini vital file: 907
Creating mini vital file: 912
Creating mini vital file: 913
Creating mini vital file: 916
Creating mini vital file: 917
Creating mini vital file: 919
Creating mini vital file: 922
Creating mini vital file: 925
Creating mini vital file: 926
Creating mini vital file: 931
Creating mini vital file: 932
Creating mini vital file: 933
Creating mini vital file: 936
Creating mini vital file: 937
Creating mini vital file: 938
Creating mini vital file: 939
Creating mini vital file: 940
Creating mini vital file: 944
Creating mini vital file: 945
Creating mini vital file: 946
Creating mini vital file: 947
Creating mini vital file: 948
Creating mini vital file: 949
Creating mini vital file: 952
Creating mini vital file: 954
Creating mini vital file: 957
Creating mini vital file: 958
Creating mini vital file: 959
Creating mini vital file: 963
Creating mini vital file: 967
Creating mini vital file: 969
Creating mini vital file: 971
Creating mini vital file: 972
Creating mini vital file: 973
Creating mini vital file: 976
Creating mini vital file: 977
Creating mini vital file: 979
Creating mini vital file: 980
Creating mini vital file: 983
Creating mini vital file: 984
Creating mini vital file: 985
Creating mini vital file: 986
Creating mini vital file: 988
Creating mini vital file: 990
Creating mini vital file: 991
Creating mini vital file: 992
Creating mini vital file: 994
Creating mini vital file: 995
Creating mini vital file: 1002
Creating mini vital file: 1003
Creating mini vital file: 1005
Creating mini vital file: 1012
Creating mini vital file: 1013
Creating mini vital file: 1015
Creating mini vital file: 1016
Creating mini vital file: 1017
Creating mini vital file: 1018
Creating mini vital file: 1020
Creating mini vital file: 1022
Creating mini vital file: 1024
Creating mini vital file: 1025
Creating mini vital file: 1026
Creating mini vital file: 1027
Creating mini vital file: 1028
Creating mini vital file: 1029
Creating mini vital file: 1030
Creating mini vital file: 1032
Creating mini vital file: 1033
Creating mini vital file: 1034
Creating mini vital file: 1035
Creating mini vital file: 1037
Creating mini vital file: 1038
Creating mini vital file: 1040
Creating mini vital file: 1041
Creating mini vital file: 1043
Creating mini vital file: 1044
Creating mini vital file: 1046
Creating mini vital file: 1047
Creating mini vital file: 1049
Creating mini vital file: 1050
Creating mini vital file: 1051
Creating mini vital file: 1055
Creating mini vital file: 1056
Creating mini vital file: 1061
Creating mini vital file: 1063
Creating mini vital file: 1065
Creating mini vital file: 1069
Creating mini vital file: 1073
Creating mini vital file: 1074
Creating mini vital file: 1076
Creating mini vital file: 1077
Creating mini vital file: 1078
Creating mini vital file: 1081
Creating mini vital file: 1083
Creating mini vital file: 1084
Creating mini vital file: 1086
Creating mini vital file: 1087
Creating mini vital file: 1088
Creating mini vital file: 1089
Creating mini vital file: 1090
Creating mini vital file: 1091
Creating mini vital file: 1093
Creating mini vital file: 1094
Creating mini vital file: 1095
Creating mini vital file: 1096
Creating mini vital file: 1097
Creating mini vital file: 1098
Creating mini vital file: 1102
Creating mini vital file: 1108
Creating mini vital file: 1109
Creating mini vital file: 1113
Creating mini vital file: 1114
Creating mini vital file: 1115
Creating mini vital file: 1118
Creating mini vital file: 1123
Creating mini vital file: 1124
Creating mini vital file: 1125
Creating mini vital file: 1127
Creating mini vital file: 1131
Creating mini vital file: 1132
Creating mini vital file: 1133
Creating mini vital file: 1135
Creating mini vital file: 1138
Creating mini vital file: 1139
Creating mini vital file: 1143
Creating mini vital file: 1144
Creating mini vital file: 1145
Creating mini vital file: 1154
Creating mini vital file: 1156
Creating mini vital file: 1158
Creating mini vital file: 1159
Creating mini vital file: 1160
Creating mini vital file: 1165
Creating mini vital file: 1166
Creating mini vital file: 1170
Creating mini vital file: 1174
Creating mini vital file: 1176
Creating mini vital file: 1180
Creating mini vital file: 1181
Creating mini vital file: 1182
Creating mini vital file: 1184
Creating mini vital file: 1185
Creating mini vital file: 1186
Creating mini vital file: 1187
Creating mini vital file: 1189
Creating mini vital file: 1190
Creating mini vital file: 1191
Creating mini vital file: 1193
Creating mini vital file: 1194
Creating mini vital file: 1196
Creating mini vital file: 1199
Creating mini vital file: 1200
Creating mini vital file: 1201
Creating mini vital file: 1202
Creating mini vital file: 1203
Creating mini vital file: 1204
Creating mini vital file: 1205
Creating mini vital file: 1208
Creating mini vital file: 1209
Creating mini vital file: 1212
Creating mini vital file: 1213
Creating mini vital file: 1215
Creating mini vital file: 1216
Creating mini vital file: 1217
Creating mini vital file: 1219
Creating mini vital file: 1221
Creating mini vital file: 1222
Creating mini vital file: 1224
Creating mini vital file: 1225
Creating mini vital file: 1228
Creating mini vital file: 1229
Creating mini vital file: 1230
Creating mini vital file: 1231
Creating mini vital file: 1232
Creating mini vital file: 1233
Creating mini vital file: 1234
Creating mini vital file: 1236
Creating mini vital file: 1237
Creating mini vital file: 1238
Creating mini vital file: 1239
Creating mini vital file: 1240
Creating mini vital file: 1244
Creating mini vital file: 1248
Creating mini vital file: 1249
Creating mini vital file: 1256
Creating mini vital file: 1261
Creating mini vital file: 1263
Creating mini vital file: 1264
Creating mini vital file: 1265
Creating mini vital file: 1267
Creating mini vital file: 1268
Creating mini vital file: 1271
Creating mini vital file: 1272
Creating mini vital file: 1275
Creating mini vital file: 1277
Creating mini vital file: 1279
Creating mini vital file: 1280
Creating mini vital file: 1283
Creating mini vital file: 1285
Creating mini vital file: 1286
Creating mini vital file: 1290
Creating mini vital file: 1291
Creating mini vital file: 1292
Creating mini vital file: 1293
Creating mini vital file: 1294
Creating mini vital file: 1297
Creating mini vital file: 1298
Creating mini vital file: 1300
Creating mini vital file: 1301
Creating mini vital file: 1302
Creating mini vital file: 1303
Creating mini vital file: 1305
Creating mini vital file: 1307
Creating mini vital file: 1309
Creating mini vital file: 1311
Creating mini vital file: 1313
Creating mini vital file: 1315
Creating mini vital file: 1316
Creating mini vital file: 1317
Creating mini vital file: 1319
Creating mini vital file: 1320
Creating mini vital file: 1321
Creating mini vital file: 1323
Creating mini vital file: 1324
Creating mini vital file: 1325
Creating mini vital file: 1333
Creating mini vital file: 1335
Creating mini vital file: 1339
Creating mini vital file: 1340
Creating mini vital file: 1341
Creating mini vital file: 1343
Creating mini vital file: 1344
Creating mini vital file: 1346
Creating mini vital file: 1347
Creating mini vital file: 1350
Creating mini vital file: 1353
Creating mini vital file: 1356
Creating mini vital file: 1358
Creating mini vital file: 1359
Creating mini vital file: 1362
Creating mini vital file: 1364
Creating mini vital file: 1365
Creating mini vital file: 1367
Creating mini vital file: 1368
Creating mini vital file: 1369
Creating mini vital file: 1374
Creating mini vital file: 1375
Creating mini vital file: 1376
Creating mini vital file: 1381
Creating mini vital file: 1383
Creating mini vital file: 1386
Creating mini vital file: 1389
Creating mini vital file: 1392
Creating mini vital file: 1396
Creating mini vital file: 1397
Creating mini vital file: 1398
Creating mini vital file: 1399
Creating mini vital file: 1402
Creating mini vital file: 1403
Creating mini vital file: 1404
Creating mini vital file: 1407
Creating mini vital file: 1408
Creating mini vital file: 1413
Creating mini vital file: 1414
Creating mini vital file: 1415
Creating mini vital file: 1416
Creating mini vital file: 1417
Creating mini vital file: 1421
Creating mini vital file: 1422
Creating mini vital file: 1426
Creating mini vital file: 1428
Creating mini vital file: 1432
Creating mini vital file: 1434
Creating mini vital file: 1436
Creating mini vital file: 1438
Creating mini vital file: 1439
Creating mini vital file: 1440
Creating mini vital file: 1442
Creating mini vital file: 1444
Creating mini vital file: 1446
Creating mini vital file: 1451
Creating mini vital file: 1452
Creating mini vital file: 1454
Creating mini vital file: 1456
Creating mini vital file: 1458
Creating mini vital file: 1463
Creating mini vital file: 1465
Creating mini vital file: 1468
Creating mini vital file: 1469
Creating mini vital file: 1470
Creating mini vital file: 1471
Creating mini vital file: 1473
Creating mini vital file: 1474
Creating mini vital file: 1475
Creating mini vital file: 1478
Creating mini vital file: 1479
Creating mini vital file: 1482
Creating mini vital file: 1485
Creating mini vital file: 1486
Creating mini vital file: 1487
Creating mini vital file: 1488
Creating mini vital file: 1489
Creating mini vital file: 1490
Creating mini vital file: 1492
Creating mini vital file: 1493
Creating mini vital file: 1496
Creating mini vital file: 1497
Creating mini vital file: 1498
Creating mini vital file: 1500
Creating mini vital file: 1503
Creating mini vital file: 1505
Creating mini vital file: 1512
Creating mini vital file: 1515
Creating mini vital file: 1520
Creating mini vital file: 1521
Creating mini vital file: 1522
Creating mini vital file: 1523
Creating mini vital file: 1525
Creating mini vital file: 1526
Creating mini vital file: 1527
Creating mini vital file: 1536
Creating mini vital file: 1537
Creating mini vital file: 1539
Creating mini vital file: 1540
Creating mini vital file: 1541
Creating mini vital file: 1542
Creating mini vital file: 1545
Creating mini vital file: 1546
Creating mini vital file: 1548
Creating mini vital file: 1549
Creating mini vital file: 1552
Creating mini vital file: 1553
Creating mini vital file: 1554
Creating mini vital file: 1555
Creating mini vital file: 1556
Creating mini vital file: 1558
Creating mini vital file: 1559
Creating mini vital file: 1561
Creating mini vital file: 1562
Creating mini vital file: 1563
Creating mini vital file: 1564
Creating mini vital file: 1566
Creating mini vital file: 1567
Creating mini vital file: 1568
Creating mini vital file: 1574
Creating mini vital file: 1575
Creating mini vital file: 1580
Creating mini vital file: 1581
Creating mini vital file: 1583
Creating mini vital file: 1585
Creating mini vital file: 1586
Creating mini vital file: 1590
Creating mini vital file: 1591
Creating mini vital file: 1594
Creating mini vital file: 1595
Creating mini vital file: 1596
Creating mini vital file: 1597
Creating mini vital file: 1599
Creating mini vital file: 1600
Creating mini vital file: 1602
Creating mini vital file: 1605
Creating mini vital file: 1608
Creating mini vital file: 1610
Creating mini vital file: 1611
Creating mini vital file: 1612
Creating mini vital file: 1613
Creating mini vital file: 1614
Creating mini vital file: 1615
Creating mini vital file: 1616
Creating mini vital file: 1618
Creating mini vital file: 1620
Creating mini vital file: 1623
Creating mini vital file: 1630
Creating mini vital file: 1632
Creating mini vital file: 1633
Creating mini vital file: 1636
Creating mini vital file: 1639
Creating mini vital file: 1641
Creating mini vital file: 1642
Creating mini vital file: 1647
Creating mini vital file: 1648
Creating mini vital file: 1656
Creating mini vital file: 1657
Creating mini vital file: 1658
Creating mini vital file: 1662
Creating mini vital file: 1665
Creating mini vital file: 1666
Creating mini vital file: 1668
Creating mini vital file: 1671
Creating mini vital file: 1672
Creating mini vital file: 1673
Creating mini vital file: 1674
Creating mini vital file: 1675
Creating mini vital file: 1676
Creating mini vital file: 1681
Creating mini vital file: 1684
Creating mini vital file: 1685
Creating mini vital file: 1687
Creating mini vital file: 1688
Creating mini vital file: 1689
Creating mini vital file: 1690
Creating mini vital file: 1694
Creating mini vital file: 1695
Creating mini vital file: 1696
Creating mini vital file: 1697
Creating mini vital file: 1699
Creating mini vital file: 1700
Creating mini vital file: 1703
Creating mini vital file: 1705
Creating mini vital file: 1706
Creating mini vital file: 1708
Creating mini vital file: 1710
Creating mini vital file: 1714
Creating mini vital file: 1716
Creating mini vital file: 1718
Creating mini vital file: 1719
Creating mini vital file: 1722
Creating mini vital file: 1724
Creating mini vital file: 1726
Creating mini vital file: 1728
Creating mini vital file: 1729
Creating mini vital file: 1730
Creating mini vital file: 1732
Creating mini vital file: 1733
Creating mini vital file: 1735
Creating mini vital file: 1737
Creating mini vital file: 1738
Creating mini vital file: 1743
Creating mini vital file: 1745
Creating mini vital file: 1747
Creating mini vital file: 1748
Creating mini vital file: 1749
Creating mini vital file: 1752
Creating mini vital file: 1753
Creating mini vital file: 1756
Creating mini vital file: 1757
Creating mini vital file: 1759
Creating mini vital file: 1761
Creating mini vital file: 1762
Creating mini vital file: 1763
Creating mini vital file: 1765
Creating mini vital file: 1766
Creating mini vital file: 1768
Creating mini vital file: 1771
Creating mini vital file: 1773
Creating mini vital file: 1775
Creating mini vital file: 1777
Creating mini vital file: 1779
Creating mini vital file: 1783
Creating mini vital file: 1784
Creating mini vital file: 1785
Creating mini vital file: 1793
Creating mini vital file: 1799
Creating mini vital file: 1800
Creating mini vital file: 1802
Creating mini vital file: 1803
Creating mini vital file: 1805
Creating mini vital file: 1809
Creating mini vital file: 1810
Creating mini vital file: 1812
Creating mini vital file: 1814
Creating mini vital file: 1816
Creating mini vital file: 1819
Creating mini vital file: 1820
Creating mini vital file: 1822
Creating mini vital file: 1823
Creating mini vital file: 1825
Creating mini vital file: 1826
Creating mini vital file: 1832
Creating mini vital file: 1833
Creating mini vital file: 1834
Creating mini vital file: 1835
Creating mini vital file: 1836
Creating mini vital file: 1837
Creating mini vital file: 1838
Creating mini vital file: 1840
Creating mini vital file: 1843
Creating mini vital file: 1844
Creating mini vital file: 1846
Creating mini vital file: 1848
Creating mini vital file: 1852
Creating mini vital file: 1853
Creating mini vital file: 1854
Creating mini vital file: 1855
Creating mini vital file: 1862
Creating mini vital file: 1864
Creating mini vital file: 1865
Creating mini vital file: 1866
Creating mini vital file: 1869
Creating mini vital file: 1872
Creating mini vital file: 1873
Creating mini vital file: 1874
Creating mini vital file: 1875
Creating mini vital file: 1876
Creating mini vital file: 1882
Creating mini vital file: 1884
Creating mini vital file: 1885
Creating mini vital file: 1886
Creating mini vital file: 1888
Creating mini vital file: 1891
Creating mini vital file: 1892
Creating mini vital file: 1893
Creating mini vital file: 1894
Creating mini vital file: 1896
Creating mini vital file: 1898
Creating mini vital file: 1899
Creating mini vital file: 1900
Creating mini vital file: 1901
Creating mini vital file: 1903
Creating mini vital file: 1907
Creating mini vital file: 1910
Creating mini vital file: 1912
Creating mini vital file: 1913
Creating mini vital file: 1914
Creating mini vital file: 1915
Creating mini vital file: 1916
Creating mini vital file: 1918
Creating mini vital file: 1920
Creating mini vital file: 1922
Creating mini vital file: 1925
Creating mini vital file: 1926
Creating mini vital file: 1928
Creating mini vital file: 1931
Creating mini vital file: 1932
Creating mini vital file: 1933
Creating mini vital file: 1934
Creating mini vital file: 1935
Creating mini vital file: 1936
Creating mini vital file: 1937
Creating mini vital file: 1938
Creating mini vital file: 1941
Creating mini vital file: 1942
Creating mini vital file: 1943
Creating mini vital file: 1944
Creating mini vital file: 1947
Creating mini vital file: 1949
Creating mini vital file: 1950
Creating mini vital file: 1955
Creating mini vital file: 1956
Creating mini vital file: 1957
Creating mini vital file: 1959
Creating mini vital file: 1961
Creating mini vital file: 1963
Creating mini vital file: 1965
Creating mini vital file: 1966
Creating mini vital file: 1969
Creating mini vital file: 1973
Creating mini vital file: 1976
Creating mini vital file: 1978
Creating mini vital file: 1985
Creating mini vital file: 1986
Creating mini vital file: 1988
Creating mini vital file: 1993
Creating mini vital file: 1994
Creating mini vital file: 1995
Creating mini vital file: 1996
Creating mini vital file: 2000
Creating mini vital file: 2002
Creating mini vital file: 2004
Creating mini vital file: 2009
Creating mini vital file: 2010
Creating mini vital file: 2011
Creating mini vital file: 2012
Creating mini vital file: 2014
Creating mini vital file: 2017
Creating mini vital file: 2018
Creating mini vital file: 2020
Creating mini vital file: 2025
Creating mini vital file: 2026
Creating mini vital file: 2028
Creating mini vital file: 2029
Creating mini vital file: 2034
Creating mini vital file: 2040
Creating mini vital file: 2041
Creating mini vital file: 2044
Creating mini vital file: 2046
Creating mini vital file: 2049
Creating mini vital file: 2051
Creating mini vital file: 2055
Creating mini vital file: 2057
Creating mini vital file: 2058
Creating mini vital file: 2060
Creating mini vital file: 2061
Creating mini vital file: 2062
Creating mini vital file: 2064
Creating mini vital file: 2066
Creating mini vital file: 2067
Creating mini vital file: 2068
Creating mini vital file: 2072
Creating mini vital file: 2074
Creating mini vital file: 2075
Creating mini vital file: 2081
Creating mini vital file: 2082
Creating mini vital file: 2086
Creating mini vital file: 2088
Creating mini vital file: 2097
Creating mini vital file: 2098
Creating mini vital file: 2106
Creating mini vital file: 2111
Creating mini vital file: 2112
Creating mini vital file: 2114
Creating mini vital file: 2117
Creating mini vital file: 2118
Creating mini vital file: 2121
Creating mini vital file: 2130
Creating mini vital file: 2132
Creating mini vital file: 2133
Creating mini vital file: 2135
Creating mini vital file: 2136
Creating mini vital file: 2139
Creating mini vital file: 2142
Creating mini vital file: 2147
Creating mini vital file: 2148
Creating mini vital file: 2149
Creating mini vital file: 2150
Creating mini vital file: 2153
Creating mini vital file: 2154
Creating mini vital file: 2157
Creating mini vital file: 2158
Creating mini vital file: 2161
Creating mini vital file: 2162
Creating mini vital file: 2163
Creating mini vital file: 2165
Creating mini vital file: 2168
Creating mini vital file: 2169
Creating mini vital file: 2170
Creating mini vital file: 2172
Creating mini vital file: 2174
Creating mini vital file: 2175
Creating mini vital file: 2176
Creating mini vital file: 2178
Creating mini vital file: 2183
Creating mini vital file: 2185
Creating mini vital file: 2187
Creating mini vital file: 2192
Creating mini vital file: 2194
Creating mini vital file: 2195
Creating mini vital file: 2196
Creating mini vital file: 2197
Creating mini vital file: 2201
Creating mini vital file: 2205
Creating mini vital file: 2206
Creating mini vital file: 2210
Creating mini vital file: 2213
Creating mini vital file: 2214
Creating mini vital file: 2218
Creating mini vital file: 2219
Creating mini vital file: 2221
Creating mini vital file: 2222
Creating mini vital file: 2223
Creating mini vital file: 2224
Creating mini vital file: 2225
Creating mini vital file: 2229
Creating mini vital file: 2231
Creating mini vital file: 2236
Creating mini vital file: 2238
Creating mini vital file: 2241
Creating mini vital file: 2242
Creating mini vital file: 2243
Creating mini vital file: 2244
Creating mini vital file: 2246
Creating mini vital file: 2248
Creating mini vital file: 2249
Creating mini vital file: 2251
Creating mini vital file: 2252
Creating mini vital file: 2253
Creating mini vital file: 2255
Creating mini vital file: 2258
Creating mini vital file: 2261
Creating mini vital file: 2265
Creating mini vital file: 2267
Creating mini vital file: 2272
Creating mini vital file: 2273
Creating mini vital file: 2275
Creating mini vital file: 2279
Creating mini vital file: 2280
Creating mini vital file: 2281
Creating mini vital file: 2282
Creating mini vital file: 2283
Creating mini vital file: 2284
Creating mini vital file: 2291
Creating mini vital file: 2295
Creating mini vital file: 2296
Creating mini vital file: 2298
Creating mini vital file: 2299
Creating mini vital file: 2300
Creating mini vital file: 2302
Creating mini vital file: 2304
Creating mini vital file: 2305
Creating mini vital file: 2306
Creating mini vital file: 2307
Creating mini vital file: 2309
Creating mini vital file: 2310
Creating mini vital file: 2311
Creating mini vital file: 2313
Creating mini vital file: 2315
Creating mini vital file: 2317
Creating mini vital file: 2318
Creating mini vital file: 2319
Creating mini vital file: 2321
Creating mini vital file: 2324
Creating mini vital file: 2325
Creating mini vital file: 2326
Creating mini vital file: 2327
Creating mini vital file: 2331
Creating mini vital file: 2332
Creating mini vital file: 2333
Creating mini vital file: 2334
Creating mini vital file: 2335
Creating mini vital file: 2336
Creating mini vital file: 2337
Creating mini vital file: 2339
Creating mini vital file: 2340
Creating mini vital file: 2341
Creating mini vital file: 2345
Creating mini vital file: 2346
Creating mini vital file: 2348
Creating mini vital file: 2349
Creating mini vital file: 2352
Creating mini vital file: 2353
Creating mini vital file: 2354
Creating mini vital file: 2356
Creating mini vital file: 2357
Creating mini vital file: 2359
Creating mini vital file: 2364
Creating mini vital file: 2365
Creating mini vital file: 2371
Creating mini vital file: 2372
Creating mini vital file: 2373
Creating mini vital file: 2375
Creating mini vital file: 2377
Creating mini vital file: 2379
Creating mini vital file: 2380
Creating mini vital file: 2382
Creating mini vital file: 2383
Creating mini vital file: 2389
Creating mini vital file: 2392
Creating mini vital file: 2393
Creating mini vital file: 2394
Creating mini vital file: 2396
Creating mini vital file: 2401
Creating mini vital file: 2405
Creating mini vital file: 2409
Creating mini vital file: 2411
Creating mini vital file: 2412
Creating mini vital file: 2413
Creating mini vital file: 2416
Creating mini vital file: 2417
Creating mini vital file: 2419
Creating mini vital file: 2420
Creating mini vital file: 2421
Creating mini vital file: 2422
Creating mini vital file: 2424
Creating mini vital file: 2425
Creating mini vital file: 2427
Creating mini vital file: 2428
Creating mini vital file: 2432
Creating mini vital file: 2433
Creating mini vital file: 2434
Creating mini vital file: 2435
Creating mini vital file: 2436
Creating mini vital file: 2438
Creating mini vital file: 2441
Creating mini vital file: 2442
Creating mini vital file: 2443
Creating mini vital file: 2444
Creating mini vital file: 2445
Creating mini vital file: 2447
Creating mini vital file: 2450
Creating mini vital file: 2452
Creating mini vital file: 2453
Creating mini vital file: 2455
Creating mini vital file: 2458
Creating mini vital file: 2460
Creating mini vital file: 2462
Creating mini vital file: 2466
Creating mini vital file: 2469
Creating mini vital file: 2470
Creating mini vital file: 2471
Creating mini vital file: 2472
Creating mini vital file: 2473
Creating mini vital file: 2474
Creating mini vital file: 2479
Creating mini vital file: 2480
Creating mini vital file: 2481
Creating mini vital file: 2482
Creating mini vital file: 2483
Creating mini vital file: 2485
Creating mini vital file: 2487
Creating mini vital file: 2489
Creating mini vital file: 2493
Creating mini vital file: 2494
Creating mini vital file: 2495
Creating mini vital file: 2496
Creating mini vital file: 2497
Creating mini vital file: 2500
Creating mini vital file: 2501
Creating mini vital file: 2503
Creating mini vital file: 2507
Creating mini vital file: 2508
Creating mini vital file: 2509
Creating mini vital file: 2510
Creating mini vital file: 2511
Creating mini vital file: 2516
Creating mini vital file: 2517
Creating mini vital file: 2519
Creating mini vital file: 2521
Creating mini vital file: 2523
Creating mini vital file: 2527
Creating mini vital file: 2528
Creating mini vital file: 2532
Creating mini vital file: 2533
Creating mini vital file: 2535
Creating mini vital file: 2537
Creating mini vital file: 2539
Creating mini vital file: 2542
Creating mini vital file: 2544
Creating mini vital file: 2547
Creating mini vital file: 2549
Creating mini vital file: 2553
Creating mini vital file: 2558
Creating mini vital file: 2559
Creating mini vital file: 2561
Creating mini vital file: 2562
Creating mini vital file: 2566
Creating mini vital file: 2568
Creating mini vital file: 2569
Creating mini vital file: 2572
Creating mini vital file: 2575
Creating mini vital file: 2576
Creating mini vital file: 2578
Creating mini vital file: 2580
Creating mini vital file: 2583
Creating mini vital file: 2584
Creating mini vital file: 2585
Creating mini vital file: 2587
Creating mini vital file: 2589
Creating mini vital file: 2590
Creating mini vital file: 2593
Creating mini vital file: 2594
Creating mini vital file: 2596
Creating mini vital file: 2597
Creating mini vital file: 2601
Creating mini vital file: 2605
Creating mini vital file: 2606
Creating mini vital file: 2607
Creating mini vital file: 2608
Creating mini vital file: 2609
Creating mini vital file: 2611
Creating mini vital file: 2612
Creating mini vital file: 2613
Creating mini vital file: 2616
Creating mini vital file: 2618
Creating mini vital file: 2619
Creating mini vital file: 2622
Creating mini vital file: 2624
Creating mini vital file: 2627
Creating mini vital file: 2628
Creating mini vital file: 2630
Creating mini vital file: 2631
Creating mini vital file: 2632
Creating mini vital file: 2637
Creating mini vital file: 2639
Creating mini vital file: 2641
Creating mini vital file: 2644
Creating mini vital file: 2646
Creating mini vital file: 2648
Creating mini vital file: 2652
Creating mini vital file: 2654
Creating mini vital file: 2655
Creating mini vital file: 2656
Creating mini vital file: 2657
Creating mini vital file: 2658
Creating mini vital file: 2662
Creating mini vital file: 2663
Creating mini vital file: 2664
Creating mini vital file: 2665
Creating mini vital file: 2667
Creating mini vital file: 2670
Creating mini vital file: 2671
Creating mini vital file: 2673
Creating mini vital file: 2674
Creating mini vital file: 2676
Creating mini vital file: 2678
Creating mini vital file: 2680
Creating mini vital file: 2687
Creating mini vital file: 2688
Creating mini vital file: 2690
Creating mini vital file: 2693
Creating mini vital file: 2695
Creating mini vital file: 2697
Creating mini vital file: 2698
Creating mini vital file: 2699
Creating mini vital file: 2700
Creating mini vital file: 2701
Creating mini vital file: 2703
Creating mini vital file: 2705
Creating mini vital file: 2706
Creating mini vital file: 2712
Creating mini vital file: 2713
Creating mini vital file: 2716
Creating mini vital file: 2717
Creating mini vital file: 2722
Creating mini vital file: 2724
Creating mini vital file: 2732
Creating mini vital file: 2735
Creating mini vital file: 2736
Creating mini vital file: 2738
Creating mini vital file: 2741
Creating mini vital file: 2742
Creating mini vital file: 2744
Creating mini vital file: 2746
Creating mini vital file: 2747
Creating mini vital file: 2749
Creating mini vital file: 2750
Creating mini vital file: 2751
Creating mini vital file: 2755
Creating mini vital file: 2760
Creating mini vital file: 2761
Creating mini vital file: 2762
Creating mini vital file: 2763
Creating mini vital file: 2764
Creating mini vital file: 2765
Creating mini vital file: 2766
Creating mini vital file: 2769
Creating mini vital file: 2771
Creating mini vital file: 2774
Creating mini vital file: 2775
Creating mini vital file: 2777
Creating mini vital file: 2778
Creating mini vital file: 2779
Creating mini vital file: 2781
Creating mini vital file: 2783
Creating mini vital file: 2785
Creating mini vital file: 2788
Creating mini vital file: 2795
Creating mini vital file: 2799
Creating mini vital file: 2800
Creating mini vital file: 2803
Creating mini vital file: 2804
Creating mini vital file: 2806
Creating mini vital file: 2807
Creating mini vital file: 2809
Creating mini vital file: 2814
Creating mini vital file: 2815
Creating mini vital file: 2819
Creating mini vital file: 2820
Creating mini vital file: 2823
Creating mini vital file: 2824
Creating mini vital file: 2827
Creating mini vital file: 2828
Creating mini vital file: 2829
Creating mini vital file: 2830
Creating mini vital file: 2835
Creating mini vital file: 2836
Creating mini vital file: 2837
Creating mini vital file: 2839
Creating mini vital file: 2845
Creating mini vital file: 2847
Creating mini vital file: 2848
Creating mini vital file: 2849
Creating mini vital file: 2850
Creating mini vital file: 2851
Creating mini vital file: 2854
Creating mini vital file: 2858
Creating mini vital file: 2859
Creating mini vital file: 2860
Creating mini vital file: 2861
Creating mini vital file: 2863
Creating mini vital file: 2864
Creating mini vital file: 2868
Creating mini vital file: 2871
Creating mini vital file: 2872
Creating mini vital file: 2876
Creating mini vital file: 2877
Creating mini vital file: 2883
Creating mini vital file: 2888
Creating mini vital file: 2889
Creating mini vital file: 2890
Creating mini vital file: 2891
Creating mini vital file: 2895
Creating mini vital file: 2900
Creating mini vital file: 2903
Creating mini vital file: 2905
Creating mini vital file: 2906
Creating mini vital file: 2909
Creating mini vital file: 2910
Creating mini vital file: 2911
Creating mini vital file: 2914
Creating mini vital file: 2919
Creating mini vital file: 2922
Creating mini vital file: 2924
Creating mini vital file: 2927
Creating mini vital file: 2929
Creating mini vital file: 2930
Creating mini vital file: 2931
Creating mini vital file: 2935
Creating mini vital file: 2939
Creating mini vital file: 2940
Creating mini vital file: 2943
Creating mini vital file: 2944
Creating mini vital file: 2945
Creating mini vital file: 2947
Creating mini vital file: 2949
Creating mini vital file: 2952
Creating mini vital file: 2954
Creating mini vital file: 2955
Creating mini vital file: 2956
Creating mini vital file: 2958
Creating mini vital file: 2959
Creating mini vital file: 2960
Creating mini vital file: 2961
Creating mini vital file: 2964
Creating mini vital file: 2966
Creating mini vital file: 2970
Creating mini vital file: 2971
Creating mini vital file: 2972
Creating mini vital file: 2974
Creating mini vital file: 2975
Creating mini vital file: 2977
Creating mini vital file: 2980
Creating mini vital file: 2981
Creating mini vital file: 2982
Creating mini vital file: 2987
Creating mini vital file: 2991
Creating mini vital file: 2992
Creating mini vital file: 2993
Creating mini vital file: 2998
Creating mini vital file: 2999
Creating mini vital file: 3000
Creating mini vital file: 3001
Creating mini vital file: 3003
Creating mini vital file: 3004
Creating mini vital file: 3006
Creating mini vital file: 3009
Creating mini vital file: 3014
Creating mini vital file: 3015
Creating mini vital file: 3019
Creating mini vital file: 3020
Creating mini vital file: 3023
Creating mini vital file: 3024
Creating mini vital file: 3027
Creating mini vital file: 3028
Creating mini vital file: 3030
Creating mini vital file: 3034
Creating mini vital file: 3035
Creating mini vital file: 3037
Creating mini vital file: 3039
Creating mini vital file: 3040
Creating mini vital file: 3042
Creating mini vital file: 3044
Creating mini vital file: 3045
Creating mini vital file: 3046
Creating mini vital file: 3047
Creating mini vital file: 3048
Creating mini vital file: 3050
Creating mini vital file: 3051
Creating mini vital file: 3057
Creating mini vital file: 3058
Creating mini vital file: 3059
Creating mini vital file: 3060
Creating mini vital file: 3065
Creating mini vital file: 3070
Creating mini vital file: 3072
Creating mini vital file: 3073
Creating mini vital file: 3074
Creating mini vital file: 3075
Creating mini vital file: 3078
Creating mini vital file: 3079
Creating mini vital file: 3080
Creating mini vital file: 3082
Creating mini vital file: 3085
Creating mini vital file: 3087
Creating mini vital file: 3088
Creating mini vital file: 3090
Creating mini vital file: 3091
Creating mini vital file: 3092
Creating mini vital file: 3093
Creating mini vital file: 3094
Creating mini vital file: 3095
Creating mini vital file: 3096
Creating mini vital file: 3097
Creating mini vital file: 3098
Creating mini vital file: 3101
Creating mini vital file: 3102
Creating mini vital file: 3103
Creating mini vital file: 3106
Creating mini vital file: 3107
Creating mini vital file: 3108
Creating mini vital file: 3110
Creating mini vital file: 3112
Creating mini vital file: 3113
Creating mini vital file: 3114
Creating mini vital file: 3116
Creating mini vital file: 3118
Creating mini vital file: 3120
Creating mini vital file: 3121
Creating mini vital file: 3122
Creating mini vital file: 3125
Creating mini vital file: 3126
Creating mini vital file: 3128
Creating mini vital file: 3130
Creating mini vital file: 3133
Creating mini vital file: 3134
Creating mini vital file: 3135
Creating mini vital file: 3136
Creating mini vital file: 3137
Creating mini vital file: 3138
Creating mini vital file: 3141
Creating mini vital file: 3142
Creating mini vital file: 3145
Creating mini vital file: 3146
Creating mini vital file: 3147
Creating mini vital file: 3148
Creating mini vital file: 3149
Creating mini vital file: 3150
Creating mini vital file: 3153
Creating mini vital file: 3154
Creating mini vital file: 3155
Creating mini vital file: 3157
Creating mini vital file: 3159
Creating mini vital file: 3161
Creating mini vital file: 3164
Creating mini vital file: 3165
Creating mini vital file: 3167
Creating mini vital file: 3169
Creating mini vital file: 3170
Creating mini vital file: 3172
Creating mini vital file: 3173
Creating mini vital file: 3175
Creating mini vital file: 3176
Creating mini vital file: 3180
Creating mini vital file: 3181
Creating mini vital file: 3184
Creating mini vital file: 3186
Creating mini vital file: 3188
Creating mini vital file: 3189
Creating mini vital file: 3193
Creating mini vital file: 3194
Creating mini vital file: 3196
Creating mini vital file: 3198
Creating mini vital file: 3200
Creating mini vital file: 3202
Creating mini vital file: 3203
Creating mini vital file: 3205
Creating mini vital file: 3207
Creating mini vital file: 3208
Creating mini vital file: 3211
Creating mini vital file: 3216
Creating mini vital file: 3218
Creating mini vital file: 3221
Creating mini vital file: 3222
Creating mini vital file: 3223
Creating mini vital file: 3226
Creating mini vital file: 3228
Creating mini vital file: 3229
Creating mini vital file: 3231
Creating mini vital file: 3232
Creating mini vital file: 3233
Creating mini vital file: 3235
Creating mini vital file: 3240
Creating mini vital file: 3243
Creating mini vital file: 3247
Creating mini vital file: 3248
Creating mini vital file: 3249
Creating mini vital file: 3250
Creating mini vital file: 3255
Creating mini vital file: 3256
Creating mini vital file: 3260
Creating mini vital file: 3263
Creating mini vital file: 3267
Creating mini vital file: 3270
Creating mini vital file: 3271
Creating mini vital file: 3273
Creating mini vital file: 3275
Creating mini vital file: 3276
Creating mini vital file: 3279
Creating mini vital file: 3284
Creating mini vital file: 3286
Creating mini vital file: 3287
Creating mini vital file: 3291
Creating mini vital file: 3293
Creating mini vital file: 3295
Creating mini vital file: 3296
Creating mini vital file: 3297
Creating mini vital file: 3299
Creating mini vital file: 3304
Creating mini vital file: 3307
Creating mini vital file: 3309
Creating mini vital file: 3310
Creating mini vital file: 3311
Creating mini vital file: 3312
Creating mini vital file: 3315
Creating mini vital file: 3317
Creating mini vital file: 3318
Creating mini vital file: 3321
Creating mini vital file: 3325
Creating mini vital file: 3327
Creating mini vital file: 3328
Creating mini vital file: 3329
Creating mini vital file: 3330
Creating mini vital file: 3331
Creating mini vital file: 3333
Creating mini vital file: 3334
Creating mini vital file: 3336
Creating mini vital file: 3338
Creating mini vital file: 3340
Creating mini vital file: 3342
Creating mini vital file: 3344
Creating mini vital file: 3345
Creating mini vital file: 3348
Creating mini vital file: 3352
Creating mini vital file: 3355
Creating mini vital file: 3357
Creating mini vital file: 3358
Creating mini vital file: 3359
Creating mini vital file: 3361
Creating mini vital file: 3362
Creating mini vital file: 3363
Creating mini vital file: 3364
Creating mini vital file: 3365
Creating mini vital file: 3366
Creating mini vital file: 3367
Creating mini vital file: 3369
Creating mini vital file: 3373
Creating mini vital file: 3374
Creating mini vital file: 3375
Creating mini vital file: 3376
Creating mini vital file: 3377
Creating mini vital file: 3379
Creating mini vital file: 3380
Creating mini vital file: 3381
Creating mini vital file: 3382
Creating mini vital file: 3383
Creating mini vital file: 3385
Creating mini vital file: 3389
Creating mini vital file: 3391
Creating mini vital file: 3394
Creating mini vital file: 3396
Creating mini vital file: 3398
Creating mini vital file: 3399
Creating mini vital file: 3401
Creating mini vital file: 3404
Creating mini vital file: 3407
Creating mini vital file: 3409
Creating mini vital file: 3412
Creating mini vital file: 3413
Creating mini vital file: 3414
Creating mini vital file: 3415
Creating mini vital file: 3418
Creating mini vital file: 3422
Creating mini vital file: 3426
Creating mini vital file: 3427
Creating mini vital file: 3428
Creating mini vital file: 3429
Creating mini vital file: 3431
Creating mini vital file: 3434
Creating mini vital file: 3435
Creating mini vital file: 3436
Creating mini vital file: 3440
Creating mini vital file: 3441
Creating mini vital file: 3442
Creating mini vital file: 3447
Creating mini vital file: 3449
Creating mini vital file: 3450
Creating mini vital file: 3451
Creating mini vital file: 3453
Creating mini vital file: 3457
Creating mini vital file: 3458
Creating mini vital file: 3460
Creating mini vital file: 3462
Creating mini vital file: 3463
Creating mini vital file: 3464
Creating mini vital file: 3468
Creating mini vital file: 3470
Creating mini vital file: 3472
Creating mini vital file: 3475
Creating mini vital file: 3476
Creating mini vital file: 3478
Creating mini vital file: 3479
Creating mini vital file: 3481
Creating mini vital file: 3483
Creating mini vital file: 3488
Creating mini vital file: 3492
Creating mini vital file: 3499
Creating mini vital file: 3500
Creating mini vital file: 3501
Creating mini vital file: 3502
Creating mini vital file: 3503
Creating mini vital file: 3505
Creating mini vital file: 3506
Creating mini vital file: 3513
Creating mini vital file: 3514
Creating mini vital file: 3515
Creating mini vital file: 3516
Creating mini vital file: 3517
Creating mini vital file: 3518
Creating mini vital file: 3521
Creating mini vital file: 3524
Creating mini vital file: 3526
Creating mini vital file: 3527
Creating mini vital file: 3528
Creating mini vital file: 3529
Creating mini vital file: 3532
Creating mini vital file: 3533
Creating mini vital file: 3535
Creating mini vital file: 3537
Creating mini vital file: 3538
Creating mini vital file: 3544
Creating mini vital file: 3545
Creating mini vital file: 3546
Creating mini vital file: 3549
Creating mini vital file: 3550
Creating mini vital file: 3555
Creating mini vital file: 3558
Creating mini vital file: 3559
Creating mini vital file: 3560
Creating mini vital file: 3562
Creating mini vital file: 3564
Creating mini vital file: 3565
Creating mini vital file: 3566
Creating mini vital file: 3567
Creating mini vital file: 3568
Creating mini vital file: 3569
Creating mini vital file: 3570
Creating mini vital file: 3571
Creating mini vital file: 3572
Creating mini vital file: 3573
Creating mini vital file: 3576
Creating mini vital file: 3581
Creating mini vital file: 3582
Creating mini vital file: 3585
Creating mini vital file: 3588
Creating mini vital file: 3589
Creating mini vital file: 3593
Creating mini vital file: 3594
Creating mini vital file: 3596
Creating mini vital file: 3602
Creating mini vital file: 3603
Creating mini vital file: 3606
Creating mini vital file: 3607
Creating mini vital file: 3608
Creating mini vital file: 3609
Creating mini vital file: 3611
Creating mini vital file: 3614
Creating mini vital file: 3616
Creating mini vital file: 3618
Creating mini vital file: 3620
Creating mini vital file: 3621
Creating mini vital file: 3623
Creating mini vital file: 3625
Creating mini vital file: 3628
Creating mini vital file: 3629
Creating mini vital file: 3631
Creating mini vital file: 3642
Creating mini vital file: 3648
Creating mini vital file: 3652
Creating mini vital file: 3656
Creating mini vital file: 3658
Creating mini vital file: 3660
Creating mini vital file: 3662
Creating mini vital file: 3663
Creating mini vital file: 3668
Creating mini vital file: 3669
Creating mini vital file: 3672
Creating mini vital file: 3674
Creating mini vital file: 3677
Creating mini vital file: 3678
Creating mini vital file: 3680
Creating mini vital file: 3682
Creating mini vital file: 3686
Creating mini vital file: 3687
Creating mini vital file: 3688
Creating mini vital file: 3689
Creating mini vital file: 3690
Creating mini vital file: 3691
Creating mini vital file: 3694
Creating mini vital file: 3697
Creating mini vital file: 3699
Creating mini vital file: 3700
Creating mini vital file: 3702
Creating mini vital file: 3703
Creating mini vital file: 3704
Creating mini vital file: 3706
Creating mini vital file: 3709
Creating mini vital file: 3710
Creating mini vital file: 3711
Creating mini vital file: 3712
Creating mini vital file: 3713
Creating mini vital file: 3719
Creating mini vital file: 3722
Creating mini vital file: 3723
Creating mini vital file: 3724
Creating mini vital file: 3725
Creating mini vital file: 3727
Creating mini vital file: 3728
Creating mini vital file: 3729
Creating mini vital file: 3730
Creating mini vital file: 3732
Creating mini vital file: 3736
Creating mini vital file: 3737
Creating mini vital file: 3739
Creating mini vital file: 3740
Creating mini vital file: 3743
Creating mini vital file: 3744
Creating mini vital file: 3748
Creating mini vital file: 3749
Creating mini vital file: 3750
Creating mini vital file: 3752
Creating mini vital file: 3753
Creating mini vital file: 3757
Creating mini vital file: 3758
Creating mini vital file: 3761
Creating mini vital file: 3763
Creating mini vital file: 3764
Creating mini vital file: 3768
Creating mini vital file: 3774
Creating mini vital file: 3775
Creating mini vital file: 3776
Creating mini vital file: 3777
Creating mini vital file: 3782
Creating mini vital file: 3783
Creating mini vital file: 3784
Creating mini vital file: 3785
Creating mini vital file: 3789
Creating mini vital file: 3791
Creating mini vital file: 3793
Creating mini vital file: 3798
Creating mini vital file: 3799
Creating mini vital file: 3800
Creating mini vital file: 3802
Creating mini vital file: 3803
Creating mini vital file: 3805
Creating mini vital file: 3810
Creating mini vital file: 3812
Creating mini vital file: 3813
Creating mini vital file: 3814
Creating mini vital file: 3816
Creating mini vital file: 3817
Creating mini vital file: 3818
Creating mini vital file: 3819
Creating mini vital file: 3821
Creating mini vital file: 3822
Creating mini vital file: 3823
Creating mini vital file: 3824
Creating mini vital file: 3825
Creating mini vital file: 3828
Creating mini vital file: 3831
Creating mini vital file: 3832
Creating mini vital file: 3835
Creating mini vital file: 3836
Creating mini vital file: 3837
Creating mini vital file: 3839
Creating mini vital file: 3840
Creating mini vital file: 3842
Creating mini vital file: 3843
Creating mini vital file: 3844
Creating mini vital file: 3845
Creating mini vital file: 3846
Creating mini vital file: 3848
Creating mini vital file: 3849
Creating mini vital file: 3850
Creating mini vital file: 3854
Creating mini vital file: 3855
Creating mini vital file: 3857
Creating mini vital file: 3858
Creating mini vital file: 3859
Creating mini vital file: 3863
Creating mini vital file: 3864
Creating mini vital file: 3868
Creating mini vital file: 3870
Creating mini vital file: 3877
Creating mini vital file: 3878
Creating mini vital file: 3879
Creating mini vital file: 3881
Creating mini vital file: 3886
Creating mini vital file: 3887
Creating mini vital file: 3888
Creating mini vital file: 3889
Creating mini vital file: 3890
Creating mini vital file: 3891
Creating mini vital file: 3893
Creating mini vital file: 3894
Creating mini vital file: 3895
Creating mini vital file: 3897
Creating mini vital file: 3898
Creating mini vital file: 3902
Creating mini vital file: 3904
Creating mini vital file: 3906
Creating mini vital file: 3910
Creating mini vital file: 3912
Creating mini vital file: 3913
Creating mini vital file: 3919
Creating mini vital file: 3922
Creating mini vital file: 3925
Creating mini vital file: 3928
Creating mini vital file: 3929
Creating mini vital file: 3930
Creating mini vital file: 3931
Creating mini vital file: 3934
Creating mini vital file: 3935
Creating mini vital file: 3936
Creating mini vital file: 3937
Creating mini vital file: 3938
Creating mini vital file: 3944
Creating mini vital file: 3949
Creating mini vital file: 3950
Creating mini vital file: 3955
Creating mini vital file: 3958
Creating mini vital file: 3962
Creating mini vital file: 3963
Creating mini vital file: 3967
Creating mini vital file: 3968
Creating mini vital file: 3971
Creating mini vital file: 3972
Creating mini vital file: 3973
Creating mini vital file: 3974
Creating mini vital file: 3975
Creating mini vital file: 3976
Creating mini vital file: 3978
Creating mini vital file: 3980
Creating mini vital file: 3981
Creating mini vital file: 3986
Creating mini vital file: 3987
Creating mini vital file: 3988
Creating mini vital file: 3990
Creating mini vital file: 3991
Creating mini vital file: 3992
Creating mini vital file: 3993
Creating mini vital file: 3994
Creating mini vital file: 3998
Creating mini vital file: 3999
Creating mini vital file: 4000
Creating mini vital file: 4004
Creating mini vital file: 4005
Creating mini vital file: 4007
Creating mini vital file: 4009
Creating mini vital file: 4010
Creating mini vital file: 4011
Creating mini vital file: 4012
Creating mini vital file: 4013
Creating mini vital file: 4016
Creating mini vital file: 4017
Creating mini vital file: 4020
Creating mini vital file: 4022
Creating mini vital file: 4024
Creating mini vital file: 4026
Creating mini vital file: 4027
Creating mini vital file: 4028
Creating mini vital file: 4030
Creating mini vital file: 4032
Creating mini vital file: 4033
Creating mini vital file: 4034
Creating mini vital file: 4035
Creating mini vital file: 4036
Creating mini vital file: 4037
Creating mini vital file: 4040
Creating mini vital file: 4042
Creating mini vital file: 4043
Creating mini vital file: 4045
Creating mini vital file: 4046
Creating mini vital file: 4047
Creating mini vital file: 4048
Creating mini vital file: 4050
Creating mini vital file: 4054
Creating mini vital file: 4060
Creating mini vital file: 4062
Creating mini vital file: 4066
Creating mini vital file: 4067
Creating mini vital file: 4069
Creating mini vital file: 4070
Creating mini vital file: 4072
Creating mini vital file: 4073
Creating mini vital file: 4074
Creating mini vital file: 4077
Creating mini vital file: 4083
Creating mini vital file: 4091
Creating mini vital file: 4093
Creating mini vital file: 4098
Creating mini vital file: 4100
Creating mini vital file: 4101
Creating mini vital file: 4106
Creating mini vital file: 4107
Creating mini vital file: 4109
Creating mini vital file: 4111
Creating mini vital file: 4112
Creating mini vital file: 4114
Creating mini vital file: 4115
Creating mini vital file: 4116
Creating mini vital file: 4120
Creating mini vital file: 4122
Creating mini vital file: 4127
Creating mini vital file: 4133
Creating mini vital file: 4137
Creating mini vital file: 4140
Creating mini vital file: 4142
Creating mini vital file: 4143
Creating mini vital file: 4144
Creating mini vital file: 4146
Creating mini vital file: 4148
Creating mini vital file: 4149
Creating mini vital file: 4150
Creating mini vital file: 4152
Creating mini vital file: 4155
Creating mini vital file: 4162
Creating mini vital file: 4165
Creating mini vital file: 4166
Creating mini vital file: 4167
Creating mini vital file: 4168
Creating mini vital file: 4172
Creating mini vital file: 4173
Creating mini vital file: 4177
Creating mini vital file: 4179
Creating mini vital file: 4181
Creating mini vital file: 4183
Creating mini vital file: 4186
Creating mini vital file: 4187
Creating mini vital file: 4189
Creating mini vital file: 4191
Creating mini vital file: 4195
Creating mini vital file: 4198
Creating mini vital file: 4201
Creating mini vital file: 4202
Creating mini vital file: 4203
Creating mini vital file: 4206
Creating mini vital file: 4207
Creating mini vital file: 4208
Creating mini vital file: 4210
Creating mini vital file: 4211
Creating mini vital file: 4212
Creating mini vital file: 4213
Creating mini vital file: 4214
Creating mini vital file: 4216
Creating mini vital file: 4219
Creating mini vital file: 4222
Creating mini vital file: 4223
Creating mini vital file: 4225
Creating mini vital file: 4227
Creating mini vital file: 4233
Creating mini vital file: 4236
Creating mini vital file: 4238
Creating mini vital file: 4240
Creating mini vital file: 4241
Creating mini vital file: 4242
Creating mini vital file: 4245
Creating mini vital file: 4247
Creating mini vital file: 4249
Creating mini vital file: 4251
Creating mini vital file: 4252
Creating mini vital file: 4253
Creating mini vital file: 4254
Creating mini vital file: 4255
Creating mini vital file: 4256
Creating mini vital file: 4258
Creating mini vital file: 4259
Creating mini vital file: 4262
Creating mini vital file: 4264
Creating mini vital file: 4265
Creating mini vital file: 4268
Creating mini vital file: 4269
Creating mini vital file: 4272
Creating mini vital file: 4277
Creating mini vital file: 4278
Creating mini vital file: 4279
Creating mini vital file: 4280
Creating mini vital file: 4281
Creating mini vital file: 4282
Creating mini vital file: 4283
Creating mini vital file: 4284
Creating mini vital file: 4286
Creating mini vital file: 4287
Creating mini vital file: 4289
Creating mini vital file: 4290
Creating mini vital file: 4292
Creating mini vital file: 4293
Creating mini vital file: 4294
Creating mini vital file: 4296
Creating mini vital file: 4302
Creating mini vital file: 4304
Creating mini vital file: 4305
Creating mini vital file: 4307
Creating mini vital file: 4308
Creating mini vital file: 4309
Creating mini vital file: 4310
Creating mini vital file: 4314
Creating mini vital file: 4316
Creating mini vital file: 4317
Creating mini vital file: 4320
Creating mini vital file: 4322
Creating mini vital file: 4325
Creating mini vital file: 4326
Creating mini vital file: 4327
Creating mini vital file: 4328
Creating mini vital file: 4332
Creating mini vital file: 4333
Creating mini vital file: 4335
Creating mini vital file: 4339
Creating mini vital file: 4341
Creating mini vital file: 4345
Creating mini vital file: 4347
Creating mini vital file: 4350
Creating mini vital file: 4352
Creating mini vital file: 4354
Creating mini vital file: 4356
Creating mini vital file: 4362
Creating mini vital file: 4364
Creating mini vital file: 4367
Creating mini vital file: 4368
Creating mini vital file: 4371
Creating mini vital file: 4375
Creating mini vital file: 4377
Creating mini vital file: 4380
Creating mini vital file: 4382
Creating mini vital file: 4383
Creating mini vital file: 4385
Creating mini vital file: 4387
Creating mini vital file: 4388
Creating mini vital file: 4389
Creating mini vital file: 4390
Creating mini vital file: 4392
Creating mini vital file: 4396
Creating mini vital file: 4398
Creating mini vital file: 4400
Creating mini vital file: 4401
Creating mini vital file: 4402
Creating mini vital file: 4405
Creating mini vital file: 4406
Creating mini vital file: 4408
Creating mini vital file: 4409
Creating mini vital file: 4411
Creating mini vital file: 4414
Creating mini vital file: 4417
Creating mini vital file: 4424
Creating mini vital file: 4425
Creating mini vital file: 4426
Creating mini vital file: 4428
Creating mini vital file: 4429
Creating mini vital file: 4430
Creating mini vital file: 4432
Creating mini vital file: 4433
Creating mini vital file: 4435
Creating mini vital file: 4437
Creating mini vital file: 4439
Creating mini vital file: 4443
Creating mini vital file: 4449
Creating mini vital file: 4451
Creating mini vital file: 4453
Creating mini vital file: 4456
Creating mini vital file: 4457
Creating mini vital file: 4458
Creating mini vital file: 4459
Creating mini vital file: 4461
Creating mini vital file: 4462
Creating mini vital file: 4463
Creating mini vital file: 4464
Creating mini vital file: 4466
Creating mini vital file: 4470
Creating mini vital file: 4472
Creating mini vital file: 4474
Creating mini vital file: 4475
Creating mini vital file: 4476
Creating mini vital file: 4477
Creating mini vital file: 4478
Creating mini vital file: 4480
Creating mini vital file: 4481
Creating mini vital file: 4483
Creating mini vital file: 4485
Creating mini vital file: 4489
Creating mini vital file: 4490
Creating mini vital file: 4496
Creating mini vital file: 4497
Creating mini vital file: 4498
Creating mini vital file: 4501
Creating mini vital file: 4502
Creating mini vital file: 4503
Creating mini vital file: 4504
Creating mini vital file: 4509
Creating mini vital file: 4510
Creating mini vital file: 4515
Creating mini vital file: 4519
Creating mini vital file: 4520
Creating mini vital file: 4522
Creating mini vital file: 4525
Creating mini vital file: 4530
Creating mini vital file: 4536
Creating mini vital file: 4538
Creating mini vital file: 4540
Creating mini vital file: 4541
Creating mini vital file: 4546
Creating mini vital file: 4547
Creating mini vital file: 4549
Creating mini vital file: 4550
Creating mini vital file: 4557
Creating mini vital file: 4559
Creating mini vital file: 4561
Creating mini vital file: 4564
Creating mini vital file: 4568
Creating mini vital file: 4569
Creating mini vital file: 4572
Creating mini vital file: 4573
Creating mini vital file: 4574
Creating mini vital file: 4576
Creating mini vital file: 4577
Creating mini vital file: 4578
Creating mini vital file: 4579
Creating mini vital file: 4581
Creating mini vital file: 4584
Creating mini vital file: 4589
Creating mini vital file: 4591
Creating mini vital file: 4596
Creating mini vital file: 4597
Creating mini vital file: 4599
Creating mini vital file: 4600
Creating mini vital file: 4602
Creating mini vital file: 4603
Creating mini vital file: 4604
Creating mini vital file: 4605
Creating mini vital file: 4607
Creating mini vital file: 4609
Creating mini vital file: 4612
Creating mini vital file: 4613
Creating mini vital file: 4616
Creating mini vital file: 4617
Creating mini vital file: 4618
Creating mini vital file: 4619
Creating mini vital file: 4620
Creating mini vital file: 4621
Creating mini vital file: 4622
Creating mini vital file: 4626
Creating mini vital file: 4627
Creating mini vital file: 4631
Creating mini vital file: 4632
Creating mini vital file: 4635
Creating mini vital file: 4639
Creating mini vital file: 4640
Creating mini vital file: 4644
Creating mini vital file: 4646
Creating mini vital file: 4648
Creating mini vital file: 4650
Creating mini vital file: 4652
Creating mini vital file: 4653
Creating mini vital file: 4654
Creating mini vital file: 4655
Creating mini vital file: 4656
Creating mini vital file: 4657
Creating mini vital file: 4658
Creating mini vital file: 4660
Creating mini vital file: 4662
Creating mini vital file: 4665
Creating mini vital file: 4666
Creating mini vital file: 4670
Creating mini vital file: 4673
Creating mini vital file: 4678
Creating mini vital file: 4683
Creating mini vital file: 4684
Creating mini vital file: 4686
Creating mini vital file: 4690
Creating mini vital file: 4695
Creating mini vital file: 4700
Creating mini vital file: 4702
Creating mini vital file: 4703
Creating mini vital file: 4705
Creating mini vital file: 4706
Creating mini vital file: 4711
Creating mini vital file: 4713
Creating mini vital file: 4714
Creating mini vital file: 4715
Creating mini vital file: 4716
Creating mini vital file: 4717
Creating mini vital file: 4718
Creating mini vital file: 4721
Creating mini vital file: 4724
Creating mini vital file: 4726
Creating mini vital file: 4727
Creating mini vital file: 4729
Creating mini vital file: 4731
Creating mini vital file: 4732
Creating mini vital file: 4733
Creating mini vital file: 4739
Creating mini vital file: 4741
Creating mini vital file: 4743
Creating mini vital file: 4744
Creating mini vital file: 4745
Creating mini vital file: 4746
Creating mini vital file: 4749
Creating mini vital file: 4750
Creating mini vital file: 4752
Creating mini vital file: 4755
Creating mini vital file: 4757
Creating mini vital file: 4759
Creating mini vital file: 4761
Creating mini vital file: 4763
Creating mini vital file: 4764
Creating mini vital file: 4767
Creating mini vital file: 4768
Creating mini vital file: 4769
Creating mini vital file: 4771
Creating mini vital file: 4773
Creating mini vital file: 4775
Creating mini vital file: 4777
Creating mini vital file: 4778
Creating mini vital file: 4779
Creating mini vital file: 4780
Creating mini vital file: 4781
Creating mini vital file: 4783
Creating mini vital file: 4784
Creating mini vital file: 4785
Creating mini vital file: 4786
Creating mini vital file: 4788
Creating mini vital file: 4789
Creating mini vital file: 4790
Creating mini vital file: 4792
Creating mini vital file: 4794
Creating mini vital file: 4798
Creating mini vital file: 4800
Creating mini vital file: 4801
Creating mini vital file: 4802
Creating mini vital file: 4803
Creating mini vital file: 4805
Creating mini vital file: 4806
Creating mini vital file: 4808
Creating mini vital file: 4809
Creating mini vital file: 4813
Creating mini vital file: 4816
Creating mini vital file: 4817
Creating mini vital file: 4818
Creating mini vital file: 4820
Creating mini vital file: 4823
Creating mini vital file: 4825
Creating mini vital file: 4826
Creating mini vital file: 4828
Creating mini vital file: 4830
Creating mini vital file: 4831
Creating mini vital file: 4834
Creating mini vital file: 4835
Creating mini vital file: 4836
Creating mini vital file: 4837
Creating mini vital file: 4839
Creating mini vital file: 4841
Creating mini vital file: 4843
Creating mini vital file: 4844
Creating mini vital file: 4847
Creating mini vital file: 4851
Creating mini vital file: 4853
Creating mini vital file: 4857
Creating mini vital file: 4858
Creating mini vital file: 4859
Creating mini vital file: 4860
Creating mini vital file: 4861
Creating mini vital file: 4865
Creating mini vital file: 4869
Creating mini vital file: 4871
Creating mini vital file: 4872
Creating mini vital file: 4874
Creating mini vital file: 4875
Creating mini vital file: 4879
Creating mini vital file: 4880
Creating mini vital file: 4882
Creating mini vital file: 4883
Creating mini vital file: 4886
Creating mini vital file: 4887
Creating mini vital file: 4893
Creating mini vital file: 4894
Creating mini vital file: 4897
Creating mini vital file: 4899
Creating mini vital file: 4901
Creating mini vital file: 4902
Creating mini vital file: 4903
Creating mini vital file: 4904
Creating mini vital file: 4907
Creating mini vital file: 4911
Creating mini vital file: 4912
Creating mini vital file: 4913
Creating mini vital file: 4914
Creating mini vital file: 4916
Creating mini vital file: 4925
Creating mini vital file: 4929
Creating mini vital file: 4932
Creating mini vital file: 4933
Creating mini vital file: 4934
Creating mini vital file: 4935
Creating mini vital file: 4936
Creating mini vital file: 4938
Creating mini vital file: 4939
Creating mini vital file: 4941
Creating mini vital file: 4942
Creating mini vital file: 4943
Creating mini vital file: 4946
Creating mini vital file: 4947
Creating mini vital file: 4949
Creating mini vital file: 4951
Creating mini vital file: 4953
Creating mini vital file: 4954
Creating mini vital file: 4957
Creating mini vital file: 4958
Creating mini vital file: 4959
Creating mini vital file: 4964
Creating mini vital file: 4965
Creating mini vital file: 4966
Creating mini vital file: 4971
Creating mini vital file: 4973
Creating mini vital file: 4974
Creating mini vital file: 4976
Creating mini vital file: 4977
Creating mini vital file: 4982
Creating mini vital file: 4985
Creating mini vital file: 4987
Creating mini vital file: 4989
Creating mini vital file: 4991
Creating mini vital file: 4992
Creating mini vital file: 4995
Creating mini vital file: 4997
Creating mini vital file: 4998
Creating mini vital file: 4999
Creating mini vital file: 5001
Creating mini vital file: 5004
Creating mini vital file: 5005
Creating mini vital file: 5006
Creating mini vital file: 5008
Creating mini vital file: 5010
Creating mini vital file: 5014
Creating mini vital file: 5015
Creating mini vital file: 5018
Creating mini vital file: 5019
Creating mini vital file: 5021
Creating mini vital file: 5024
Creating mini vital file: 5027
Creating mini vital file: 5029
Creating mini vital file: 5031
Creating mini vital file: 5033
Creating mini vital file: 5036
Creating mini vital file: 5040
Creating mini vital file: 5043
Creating mini vital file: 5044
Creating mini vital file: 5045
Creating mini vital file: 5046
Creating mini vital file: 5052
Creating mini vital file: 5059
Creating mini vital file: 5060
Creating mini vital file: 5061
Creating mini vital file: 5068
Creating mini vital file: 5070
Creating mini vital file: 5072
Creating mini vital file: 5077
Creating mini vital file: 5079
Creating mini vital file: 5080
Creating mini vital file: 5084
Creating mini vital file: 5089
Creating mini vital file: 5090
Creating mini vital file: 5091
Creating mini vital file: 5092
Creating mini vital file: 5093
Creating mini vital file: 5099
Creating mini vital file: 5100
Creating mini vital file: 5104
Creating mini vital file: 5106
Creating mini vital file: 5108
Creating mini vital file: 5109
Creating mini vital file: 5110
Creating mini vital file: 5111
Creating mini vital file: 5112
Creating mini vital file: 5116
Creating mini vital file: 5117
Creating mini vital file: 5118
Creating mini vital file: 5119
Creating mini vital file: 5122
Creating mini vital file: 5124
Creating mini vital file: 5125
Creating mini vital file: 5126
Creating mini vital file: 5130
Creating mini vital file: 5131
Creating mini vital file: 5135
Creating mini vital file: 5137
Creating mini vital file: 5139
Creating mini vital file: 5140
Creating mini vital file: 5141
Creating mini vital file: 5142
Creating mini vital file: 5143
Creating mini vital file: 5148
Creating mini vital file: 5149
Creating mini vital file: 5150
Creating mini vital file: 5151
Creating mini vital file: 5152
Creating mini vital file: 5153
Creating mini vital file: 5155
Creating mini vital file: 5156
Creating mini vital file: 5157
Creating mini vital file: 5162
Creating mini vital file: 5163
Creating mini vital file: 5164
Creating mini vital file: 5166
Creating mini vital file: 5173
Creating mini vital file: 5174
Creating mini vital file: 5175
Creating mini vital file: 5178
Creating mini vital file: 5179
Creating mini vital file: 5180
Creating mini vital file: 5182
Creating mini vital file: 5183
Creating mini vital file: 5184
Creating mini vital file: 5185
Creating mini vital file: 5187
Creating mini vital file: 5192
Creating mini vital file: 5193
Creating mini vital file: 5194
Creating mini vital file: 5195
Creating mini vital file: 5198
Creating mini vital file: 5201
Creating mini vital file: 5202
Creating mini vital file: 5203
Creating mini vital file: 5204
Creating mini vital file: 5209
Creating mini vital file: 5213
Creating mini vital file: 5214
Creating mini vital file: 5217
Creating mini vital file: 5218
Creating mini vital file: 5221
Creating mini vital file: 5222
Creating mini vital file: 5223
Creating mini vital file: 5224
Creating mini vital file: 5225
Creating mini vital file: 5226
Creating mini vital file: 5229
Creating mini vital file: 5230
Creating mini vital file: 5232
Creating mini vital file: 5234
Creating mini vital file: 5235
Creating mini vital file: 5237
Creating mini vital file: 5245
Creating mini vital file: 5246
Creating mini vital file: 5247
Creating mini vital file: 5251
Creating mini vital file: 5253
Creating mini vital file: 5254
Creating mini vital file: 5255
Creating mini vital file: 5259
Creating mini vital file: 5264
Creating mini vital file: 5265
Creating mini vital file: 5266
Creating mini vital file: 5267
Creating mini vital file: 5270
Creating mini vital file: 5271
Creating mini vital file: 5274
Creating mini vital file: 5277
Creating mini vital file: 5278
Creating mini vital file: 5280
Creating mini vital file: 5283
Creating mini vital file: 5284
Creating mini vital file: 5285
Creating mini vital file: 5288
Creating mini vital file: 5292
Creating mini vital file: 5295
Creating mini vital file: 5296
Creating mini vital file: 5297
Creating mini vital file: 5298
Creating mini vital file: 5299
Creating mini vital file: 5301
Creating mini vital file: 5302
Creating mini vital file: 5304
Creating mini vital file: 5305
Creating mini vital file: 5308
Creating mini vital file: 5309
Creating mini vital file: 5310
Creating mini vital file: 5311
Creating mini vital file: 5314
Creating mini vital file: 5317
Creating mini vital file: 5319
Creating mini vital file: 5321
Creating mini vital file: 5322
Creating mini vital file: 5323
Creating mini vital file: 5324
Creating mini vital file: 5327
Creating mini vital file: 5332
Creating mini vital file: 5339
Creating mini vital file: 5342
Creating mini vital file: 5344
Creating mini vital file: 5346
Creating mini vital file: 5347
Creating mini vital file: 5348
Creating mini vital file: 5349
Creating mini vital file: 5352
Creating mini vital file: 5353
Creating mini vital file: 5356
Creating mini vital file: 5359
Creating mini vital file: 5360
Creating mini vital file: 5362
Creating mini vital file: 5363
Creating mini vital file: 5364
Creating mini vital file: 5366
Creating mini vital file: 5367
Creating mini vital file: 5368
Creating mini vital file: 5371
Creating mini vital file: 5372
Creating mini vital file: 5379
Creating mini vital file: 5383
Creating mini vital file: 5387
Creating mini vital file: 5388
Creating mini vital file: 5390
Creating mini vital file: 5393
Creating mini vital file: 5394
Creating mini vital file: 5395
Creating mini vital file: 5396
Creating mini vital file: 5397
Creating mini vital file: 5399
Creating mini vital file: 5402
Creating mini vital file: 5403
Creating mini vital file: 5406
Creating mini vital file: 5411
Creating mini vital file: 5415
Creating mini vital file: 5416
Creating mini vital file: 5420
Creating mini vital file: 5421
Creating mini vital file: 5422
Creating mini vital file: 5423
Creating mini vital file: 5425
Creating mini vital file: 5427
Creating mini vital file: 5431
Creating mini vital file: 5434
Creating mini vital file: 5436
Creating mini vital file: 5442
Creating mini vital file: 5443
Creating mini vital file: 5446
Creating mini vital file: 5449
Creating mini vital file: 5451
Creating mini vital file: 5453
Creating mini vital file: 5454
Creating mini vital file: 5456
Creating mini vital file: 5458
Creating mini vital file: 5460
Creating mini vital file: 5462
Creating mini vital file: 5463
Creating mini vital file: 5467
Creating mini vital file: 5474
Creating mini vital file: 5475
Creating mini vital file: 5476
Creating mini vital file: 5478
Creating mini vital file: 5479
Creating mini vital file: 5480
Creating mini vital file: 5484
Creating mini vital file: 5486
Creating mini vital file: 5487
Creating mini vital file: 5490
Creating mini vital file: 5492
Creating mini vital file: 5495
Creating mini vital file: 5497
Creating mini vital file: 5499
Creating mini vital file: 5500
Creating mini vital file: 5501
Creating mini vital file: 5502
Creating mini vital file: 5505
Creating mini vital file: 5507
Creating mini vital file: 5508
Creating mini vital file: 5509
Creating mini vital file: 5511
Creating mini vital file: 5513
Creating mini vital file: 5515
Creating mini vital file: 5516
Creating mini vital file: 5517
Creating mini vital file: 5519
Creating mini vital file: 5520
Creating mini vital file: 5524
Creating mini vital file: 5526
Creating mini vital file: 5531
Creating mini vital file: 5533
Creating mini vital file: 5534
Creating mini vital file: 5536
Creating mini vital file: 5537
Creating mini vital file: 5538
Creating mini vital file: 5541
Creating mini vital file: 5544
Creating mini vital file: 5546
Creating mini vital file: 5548
Creating mini vital file: 5552
Creating mini vital file: 5556
Creating mini vital file: 5561
Creating mini vital file: 5562
Creating mini vital file: 5564
Creating mini vital file: 5566
Creating mini vital file: 5568
Creating mini vital file: 5571
Creating mini vital file: 5572
Creating mini vital file: 5573
Creating mini vital file: 5574
Creating mini vital file: 5578
Creating mini vital file: 5582
Creating mini vital file: 5583
Creating mini vital file: 5585
Creating mini vital file: 5587
Creating mini vital file: 5589
Creating mini vital file: 5593
Creating mini vital file: 5594
Creating mini vital file: 5595
Creating mini vital file: 5597
Creating mini vital file: 5598
Creating mini vital file: 5600
Creating mini vital file: 5601
Creating mini vital file: 5602
Creating mini vital file: 5603
Creating mini vital file: 5607
Creating mini vital file: 5608
Creating mini vital file: 5610
Creating mini vital file: 5612
Creating mini vital file: 5613
Creating mini vital file: 5614
Creating mini vital file: 5616
Creating mini vital file: 5617
Creating mini vital file: 5618
Creating mini vital file: 5620
Creating mini vital file: 5621
Creating mini vital file: 5624
Creating mini vital file: 5626
Creating mini vital file: 5627
Creating mini vital file: 5629
Creating mini vital file: 5630
Creating mini vital file: 5633
Creating mini vital file: 5635
Creating mini vital file: 5637
Creating mini vital file: 5638
Creating mini vital file: 5641
Creating mini vital file: 5642
Creating mini vital file: 5646
Creating mini vital file: 5647
Creating mini vital file: 5648
Creating mini vital file: 5650
Creating mini vital file: 5654
Creating mini vital file: 5655
Creating mini vital file: 5657
Creating mini vital file: 5658
Creating mini vital file: 5659
Creating mini vital file: 5662
Creating mini vital file: 5664
Creating mini vital file: 5665
Creating mini vital file: 5669
Creating mini vital file: 5670
Creating mini vital file: 5671
Creating mini vital file: 5673
Creating mini vital file: 5675
Creating mini vital file: 5677
Creating mini vital file: 5678
Creating mini vital file: 5680
Creating mini vital file: 5682
Creating mini vital file: 5684
Creating mini vital file: 5685
Creating mini vital file: 5687
Creating mini vital file: 5690
Creating mini vital file: 5691
Creating mini vital file: 5692
Creating mini vital file: 5693
Creating mini vital file: 5694
Creating mini vital file: 5696
Creating mini vital file: 5698
Creating mini vital file: 5703
Creating mini vital file: 5711
Creating mini vital file: 5715
Creating mini vital file: 5717
Creating mini vital file: 5718
Creating mini vital file: 5719
Creating mini vital file: 5721
Creating mini vital file: 5724
Creating mini vital file: 5725
Creating mini vital file: 5727
Creating mini vital file: 5729
Creating mini vital file: 5733
Creating mini vital file: 5734
Creating mini vital file: 5743
Creating mini vital file: 5745
Creating mini vital file: 5746
Creating mini vital file: 5749
Creating mini vital file: 5750
Creating mini vital file: 5751
Creating mini vital file: 5753
Creating mini vital file: 5755
Creating mini vital file: 5759
Creating mini vital file: 5760
Creating mini vital file: 5765
Creating mini vital file: 5769
Creating mini vital file: 5771
Creating mini vital file: 5772
Creating mini vital file: 5777
Creating mini vital file: 5780
Creating mini vital file: 5781
Creating mini vital file: 5782
Creating mini vital file: 5783
Creating mini vital file: 5784
Creating mini vital file: 5787
Creating mini vital file: 5788
Creating mini vital file: 5793
Creating mini vital file: 5795
Creating mini vital file: 5799
Creating mini vital file: 5800
Creating mini vital file: 5801
Creating mini vital file: 5805
Creating mini vital file: 5806
Creating mini vital file: 5808
Creating mini vital file: 5809
Creating mini vital file: 5810
Creating mini vital file: 5811
Creating mini vital file: 5814
Creating mini vital file: 5816
Creating mini vital file: 5817
Creating mini vital file: 5819
Creating mini vital file: 5823
Creating mini vital file: 5825
Creating mini vital file: 5826
Creating mini vital file: 5827
Creating mini vital file: 5829
Creating mini vital file: 5831
Creating mini vital file: 5832
Creating mini vital file: 5834
Creating mini vital file: 5837
Creating mini vital file: 5839
Creating mini vital file: 5840
Creating mini vital file: 5842
Creating mini vital file: 5843
Creating mini vital file: 5844
Creating mini vital file: 5848
Creating mini vital file: 5849
Creating mini vital file: 5851
Creating mini vital file: 5859
Creating mini vital file: 5860
Creating mini vital file: 5861
Creating mini vital file: 5862
Creating mini vital file: 5864
Creating mini vital file: 5865
Creating mini vital file: 5866
Creating mini vital file: 5869
Creating mini vital file: 5870
Creating mini vital file: 5871
Creating mini vital file: 5872
Creating mini vital file: 5873
Creating mini vital file: 5875
Creating mini vital file: 5882
Creating mini vital file: 5884
Creating mini vital file: 5887
Creating mini vital file: 5888
Creating mini vital file: 5889
Creating mini vital file: 5890
Creating mini vital file: 5891
Creating mini vital file: 5892
Creating mini vital file: 5894
Creating mini vital file: 5895
Creating mini vital file: 5902
Creating mini vital file: 5904
Creating mini vital file: 5907
Creating mini vital file: 5908
Creating mini vital file: 5911
Creating mini vital file: 5912
Creating mini vital file: 5914
Creating mini vital file: 5916
Creating mini vital file: 5917
Creating mini vital file: 5918
Creating mini vital file: 5933
Creating mini vital file: 5934
Creating mini vital file: 5937
Creating mini vital file: 5938
Creating mini vital file: 5940
Creating mini vital file: 5942
Creating mini vital file: 5943
Creating mini vital file: 5944
Creating mini vital file: 5945
Creating mini vital file: 5946
Creating mini vital file: 5948
Creating mini vital file: 5950
Creating mini vital file: 5951
Creating mini vital file: 5954
Creating mini vital file: 5956
Creating mini vital file: 5958
Creating mini vital file: 5959
Creating mini vital file: 5961
Creating mini vital file: 5964
Creating mini vital file: 5965
Creating mini vital file: 5966
Creating mini vital file: 5967
Creating mini vital file: 5970
Creating mini vital file: 5971
Creating mini vital file: 5973
Creating mini vital file: 5974
Creating mini vital file: 5975
Creating mini vital file: 5976
Creating mini vital file: 5977
Creating mini vital file: 5981
Creating mini vital file: 5982
Creating mini vital file: 5983
Creating mini vital file: 5986
Creating mini vital file: 5987
Creating mini vital file: 5989
Creating mini vital file: 5993
Creating mini vital file: 5994
Creating mini vital file: 5997
Creating mini vital file: 6000
Creating mini vital file: 6003
Creating mini vital file: 6006
Creating mini vital file: 6007
Creating mini vital file: 6009
Creating mini vital file: 6010
Creating mini vital file: 6013
Creating mini vital file: 6015
Creating mini vital file: 6016
Creating mini vital file: 6017
Creating mini vital file: 6020
Creating mini vital file: 6022
Creating mini vital file: 6027
Creating mini vital file: 6028
Creating mini vital file: 6029
Creating mini vital file: 6031
Creating mini vital file: 6032
Creating mini vital file: 6037
Creating mini vital file: 6039
Creating mini vital file: 6041
Creating mini vital file: 6042
Creating mini vital file: 6043
Creating mini vital file: 6047
Creating mini vital file: 6053
Creating mini vital file: 6055
Creating mini vital file: 6056
Creating mini vital file: 6057
Creating mini vital file: 6058
Creating mini vital file: 6059
Creating mini vital file: 6060
Creating mini vital file: 6061
Creating mini vital file: 6063
Creating mini vital file: 6065
Creating mini vital file: 6066
Creating mini vital file: 6067
Creating mini vital file: 6069
Creating mini vital file: 6070
Creating mini vital file: 6071
Creating mini vital file: 6074
Creating mini vital file: 6076
Creating mini vital file: 6077
Creating mini vital file: 6080
Creating mini vital file: 6082
Creating mini vital file: 6083
Creating mini vital file: 6084
Creating mini vital file: 6085
Creating mini vital file: 6086
Creating mini vital file: 6087
Creating mini vital file: 6088
Creating mini vital file: 6089
Creating mini vital file: 6097
Creating mini vital file: 6098
Creating mini vital file: 6101
Creating mini vital file: 6102
Creating mini vital file: 6103
Creating mini vital file: 6104
Creating mini vital file: 6109
Creating mini vital file: 6114
Creating mini vital file: 6119
Creating mini vital file: 6121
Creating mini vital file: 6124
Creating mini vital file: 6126
Creating mini vital file: 6127
Creating mini vital file: 6129
Creating mini vital file: 6131
Creating mini vital file: 6132
Creating mini vital file: 6133
Creating mini vital file: 6134
Creating mini vital file: 6135
Creating mini vital file: 6136
Creating mini vital file: 6140
Creating mini vital file: 6141
Creating mini vital file: 6143
Creating mini vital file: 6144
Creating mini vital file: 6147
Creating mini vital file: 6152
Creating mini vital file: 6153
Creating mini vital file: 6154
Creating mini vital file: 6156
Creating mini vital file: 6159
Creating mini vital file: 6160
Creating mini vital file: 6163
Creating mini vital file: 6166
Creating mini vital file: 6167
Creating mini vital file: 6168
Creating mini vital file: 6169
Creating mini vital file: 6171
Creating mini vital file: 6174
Creating mini vital file: 6176
Creating mini vital file: 6178
Creating mini vital file: 6179
Creating mini vital file: 6180
Creating mini vital file: 6182
Creating mini vital file: 6184
Creating mini vital file: 6185
Creating mini vital file: 6186
Creating mini vital file: 6190
Creating mini vital file: 6191
Creating mini vital file: 6192
Creating mini vital file: 6194
Creating mini vital file: 6195
Creating mini vital file: 6196
Creating mini vital file: 6198
Creating mini vital file: 6199
Creating mini vital file: 6200
Creating mini vital file: 6204
Creating mini vital file: 6205
Creating mini vital file: 6206
Creating mini vital file: 6208
Creating mini vital file: 6210
Creating mini vital file: 6214
Creating mini vital file: 6217
Creating mini vital file: 6218
Creating mini vital file: 6219
Creating mini vital file: 6220
Creating mini vital file: 6224
Creating mini vital file: 6227
Creating mini vital file: 6228
Creating mini vital file: 6230
Creating mini vital file: 6233
Creating mini vital file: 6235
Creating mini vital file: 6238
Creating mini vital file: 6239
Creating mini vital file: 6240
Creating mini vital file: 6241
Creating mini vital file: 6248
Creating mini vital file: 6250
Creating mini vital file: 6254
Creating mini vital file: 6255
Creating mini vital file: 6257
Creating mini vital file: 6260
Creating mini vital file: 6261
Creating mini vital file: 6262
Creating mini vital file: 6264
Creating mini vital file: 6266
Creating mini vital file: 6267
Creating mini vital file: 6268
Creating mini vital file: 6269
Creating mini vital file: 6270
Creating mini vital file: 6271
Creating mini vital file: 6273
Creating mini vital file: 6275
Creating mini vital file: 6277
Creating mini vital file: 6279
Creating mini vital file: 6280
Creating mini vital file: 6281
Creating mini vital file: 6282
Creating mini vital file: 6284
Creating mini vital file: 6286
Creating mini vital file: 6289
Creating mini vital file: 6290
Creating mini vital file: 6292
Creating mini vital file: 6293
Creating mini vital file: 6295
Creating mini vital file: 6296
Creating mini vital file: 6297
Creating mini vital file: 6298
Creating mini vital file: 6302
Creating mini vital file: 6305
Creating mini vital file: 6306
Creating mini vital file: 6307
Creating mini vital file: 6309
Creating mini vital file: 6311
Creating mini vital file: 6312
Creating mini vital file: 6314
Creating mini vital file: 6315
Creating mini vital file: 6316
Creating mini vital file: 6317
Creating mini vital file: 6324
Creating mini vital file: 6330
Creating mini vital file: 6331
Creating mini vital file: 6332
Creating mini vital file: 6339
Creating mini vital file: 6343
Creating mini vital file: 6345
Creating mini vital file: 6346
Creating mini vital file: 6351
Creating mini vital file: 6355
Creating mini vital file: 6357
Creating mini vital file: 6359
Creating mini vital file: 6360
Creating mini vital file: 6361
Creating mini vital file: 6362
Creating mini vital file: 6363
Creating mini vital file: 6366
Creating mini vital file: 6368
Creating mini vital file: 6370
Creating mini vital file: 6372
Creating mini vital file: 6373
Creating mini vital file: 6375
Creating mini vital file: 6376
Creating mini vital file: 6378
Creating mini vital file: 6381
Creating mini vital file: 6383
Creating mini vital file: 6385
Creating mini vital file: 6386
Creating mini vital file: 6388

Count of cases of interest:           3110
Count of vital files minified:        3110
Count of vital files already present: 0
Count of vital files missing tracks:  0
Count of vital files not fixable:     0

Filtering¶

Preprocessing characteristics are different for each of the three signal categories:

  • ABP: no preprocessing, use as-is
  • ECG: apply a 1-40Hz bandpass filter, then perform Z-score normalization
  • EEG: apply a 0.5-50Hz bandpass filter

apply_bandpass_filter() implements the bandpass filter using scipy.signal

apply_zscore_normalization() implements the Z-score normalization using numpy

In [29]:
from scipy.signal import butter, lfilter, spectrogram

# define two methods for data preprocessing

def apply_bandpass_filter(data, lowcut, highcut, fs, order=5):
    b, a = butter(order, [lowcut, highcut], fs=fs, btype='band')
    y = lfilter(b, a, np.nan_to_num(data))
    return y

def apply_zscore_normalization(signal):
    mean = np.nanmean(signal)
    std = np.nanstd(signal)
    return (signal - mean) / std
In [30]:
# Filtering Demonstration

# temp experimental, code to be incorporated into overall preloader process
# for now it's just dumping example plots of the before/after filtered signal data
caseidx = 1
file_path = f"{VITAL_MINI}/{caseidx:04d}_mini.vital"
vf = vitaldb.VitalFile(file_path, TRACK_NAMES)

originalAbp = None
filteredAbp = None
originalEcg = None
filteredEcg = None
originalEeg = None
filteredEeg = None

ABP_TRACK_NAME = "SNUADC/ART"
ECG_TRACK_NAME = "SNUADC/ECG_II"
EEG_TRACK_NAME = "BIS/EEG1_WAV"

for i, (track_name, rate) in enumerate(zip(TRACK_NAMES, TRACK_SRATES)):
    # Get samples for this track
    track_samples = vf.get_track_samples(track_name, 1/rate)
    #track_samples, _ = vf.get_samples(track_name, 1/rate)
    print(f"Track {track_name} @ {rate}Hz shape {len(track_samples)}")

    if track_name == ABP_TRACK_NAME:
        # ABP waveforms are used without further pre-processing
        originalAbp = track_samples
        filteredAbp = track_samples
    elif track_name == ECG_TRACK_NAME:
        originalEcg = track_samples
        # ECG waveforms are band-pass filtered between 1 and 40 Hz, and Z-score normalized
        # first apply bandpass filter
        filteredEcg = apply_bandpass_filter(track_samples, 1, 40, rate)
        # then do z-score normalization
        filteredEcg = apply_zscore_normalization(filteredEcg)
    elif track_name == EEG_TRACK_NAME:
        # EEG waveforms are band-pass filtered between 0.5 and 50 Hz
        originalEeg = track_samples
        filteredEeg = apply_bandpass_filter(track_samples, 0.5, 50, rate, 2)

def plotSignal(data, title):
    plt.figure(figsize=(20, 5))
    plt.plot(data)
    plt.title(title)
    plt.show()

plotSignal(originalAbp, "Original ABP")
plotSignal(originalAbp, "Unfiltered ABP")
plotSignal(originalEcg, "Original ECG")
plotSignal(filteredEcg, "Filtered ECG")
plotSignal(originalEeg, "Original EEG")
plotSignal(filteredEeg, "Filtered EEG")
Track SNUADC/ART @ 500Hz shape 5771049
Track SNUADC/ECG_II @ 500Hz shape 5771049
Track BIS/EEG1_WAV @ 128Hz shape 1477389
In [31]:
# Preprocess data tracks
ABP_TRACK_NAME = "SNUADC/ART"
ECG_TRACK_NAME = "SNUADC/ECG_II"
EEG_TRACK_NAME = "BIS/EEG1_WAV"
EVENT_TRACK_NAME = "EVENT"
MINI_FILE_FOLDER = VITAL_MINI
CACHE_FILE_FOLDER = VITAL_PREPROCESS_SCRATCH

if RESET_CACHE:
    TRACK_CACHE = None
    SEGMENT_CACHE = None

if TRACK_CACHE is None:
    TRACK_CACHE = {}
    SEGMENT_CACHE = {}

def get_track_data(case, print_when_file_loaded = False):
    parsedFile = None
    abp = None
    eeg = None
    ecg = None
    events = None

    for i, (track_name, rate) in enumerate(zip(EXTRACTION_TRACK_NAMES, EXTRACTION_TRACK_SRATES)):
        # use integer case id and track name, delimited by pipe, as cache key
        cache_label = f"{case}|{track_name}"
        
        if cache_label not in TRACK_CACHE:
            if parsedFile is None:
                file_path = f"{MINI_FILE_FOLDER}/{case:04d}_mini.vital"
                if print_when_file_loaded:
                    print(f"[{datetime.now()}] Loading vital file {file_path}")
                parsedFile = vitaldb.VitalFile(file_path, EXTRACTION_TRACK_NAMES)
            
            dataset = np.array(parsedFile.get_track_samples(track_name, 1/rate))
            
            if track_name == ABP_TRACK_NAME:
                # no filtering for ABP
                abp = dataset
                abp = pd.DataFrame(abp).ffill(axis=0).bfill(axis=0)[0].values
                if USE_MEMORY_CACHING:
                    TRACK_CACHE[cache_label] = abp
            elif track_name == ECG_TRACK_NAME:
                ecg = dataset
                # apply ECG filtering: first bandpass then do z-score normalization
                ecg = pd.DataFrame(ecg).ffill(axis=0).bfill(axis=0)[0].values
                ecg = apply_bandpass_filter(ecg, 1, 40, rate, 2)
                ecg = apply_zscore_normalization(ecg)
                
                if USE_MEMORY_CACHING:
                    TRACK_CACHE[cache_label] = ecg
            elif track_name == EEG_TRACK_NAME:
                eeg = dataset
                eeg = pd.DataFrame(eeg).ffill(axis=0).bfill(axis=0)[0].values
                # apply EEG filtering: bandpass only
                eeg = apply_bandpass_filter(eeg, 0.5, 50, rate, 2)
                if USE_MEMORY_CACHING:
                    TRACK_CACHE[cache_label] = eeg
            elif track_name == EVENT_TRACK_NAME:
                events = dataset
                if USE_MEMORY_CACHING:
                    TRACK_CACHE[cache_label] = events
        else:
            # cache hit, pull from cache
            if track_name == ABP_TRACK_NAME:
                abp = TRACK_CACHE[cache_label]
            elif track_name == ECG_TRACK_NAME:
                ecg = TRACK_CACHE[cache_label]
            elif track_name == EEG_TRACK_NAME:
                eeg = TRACK_CACHE[cache_label]
            elif track_name == EVENT_TRACK_NAME:
                events = TRACK_CACHE[cache_label]

    return (abp, ecg, eeg, events)

# ABP waveforms are used without further pre-processing
# ECG waveforms are band-pass filtered between 1 and 40 Hz, and Z-score normalized
# EEG waveforms are band-pass filtered between 0.5 and 50 Hz
if PRELOADING_CASES:
    # determine disk cache file label
    maxlabel = "ALL"
    if MAX_CASES is not None:
        maxlabel = str(MAX_CASES)
    picklefile = f"{CACHE_FILE_FOLDER}/{PREDICTION_WINDOW}_minutes_MAX{maxlabel}.trackcache"

    for track in tqdm(cases_of_interest_idx):
        # getting track data will cause a cache-check and fill when missing
        # will also apply appropriate filtering per track
        get_track_data(track, False)
    
    print(f"Generated track cache, {len(TRACK_CACHE)} records generated")


def get_segment_data(file_path):
    abp = None
    eeg = None
    ecg = None

    if USE_MEMORY_CACHING:
        if file_path in SEGMENT_CACHE:
            (abp, ecg, eeg) = SEGMENT_CACHE[file_path]
            return (abp, ecg, eeg)

    try:
        with h5py.File(file_path, 'r') as f:
            abp = np.array(f['abp'])
            ecg = np.array(f['ecg'])
            eeg = np.array(f['eeg'])
        
        abp = np.array(abp)
        eeg = np.array(eeg)
        ecg = np.array(ecg)

        if len(abp) > 30000:
            abp = abp[:30000]
        elif len(ecg) < 30000:
            abp = np.resize(abp, (30000))

        if len(ecg) > 30000:
            ecg = ecg[:30000]
        elif len(ecg) < 30000:
            ecg = np.resize(ecg, (30000))

        if len(eeg) > 7680:
            eeg = eeg[:7680]
        elif len(eeg) < 7680:
            eeg = np.resize(eeg, (7680))

        if USE_MEMORY_CACHING:
            SEGMENT_CACHE[file_path] = (abp, ecg, eeg)
    except:
        abp = None
        ecg = None
        eeg = None

    return (abp, ecg, eeg)

The following method is adapted from the preprocessing block of reference [6] (https://github.com/vitaldb/examples/blob/master/hypotension_art.ipynb)

The approach first finds an interoperative hypotensive event in the ABP waveform. It then backtracks to earlier in the waveform to extract a 60 second segment representing the waveform feature to use as model input. The figure below shows an example of this approach and is reproduced from the VitalDB example notebook referenced above.

Feature segment extraction

In [32]:
def getSurgeryBoundariesInSeconds(event, debug=False):
    eventIndices = np.argwhere(event==event)
    # we are looking for the last index where the string contains 'start
    lastStart = 0
    firstFinish = len(event)-1
    
    # find last start
    for idx in eventIndices:
        if 'started' in event[idx[0]]:
            if debug:
                print(event[idx[0]])
                print(idx[0])
            lastStart = idx[0]
    
    # find first finish
    for idx in eventIndices:
        if 'finish' in event[idx[0]]:
            if debug:
                print(event[idx[0]])
                print(idx[0])

            firstFinish = idx[0]
            break
    
    if debug:
        print(f'lastStart, firstFinish: {lastStart}, {firstFinish}')
    return (lastStart, firstFinish)
In [33]:
def areCaseSegmentsCached(caseid):
    seg_folder = f"{VITAL_EXTRACTED_SEGMENTS}/{caseid:04d}"
    return os.path.exists(seg_folder) and len(os.listdir(seg_folder)) > 0
In [34]:
def isAbpSegmentValidNumpy(samples, debug=False):
    valid = True
    if np.isnan(samples).mean() > 0.1:
        valid = False
        if debug:
            print(f">10% NaN")
    elif (samples > 200).any():
        valid = False
        if debug:
            print(f"Presence of BP > 200")
    elif (samples < 30).any():
        valid = False
        if debug:
            print(f"Presence of BP < 30")
    elif np.max(samples) - np.min(samples) < 30:
        if debug:
            print(f"Max - Min test < 30")
        valid = False
    elif (np.abs(np.diff(samples)) > 30).any():  # abrupt change -> noise
        if debug:
            print(f"Abrupt change (noise)")
        valid = False
    
    return valid
In [35]:
def isAbpSegmentValid(vf, debug=False):
    ABP_ECG_SRATE_HZ = 500
    ABP_TRACK_NAME = "SNUADC/ART"

    samples = np.array(vf.get_track_samples(ABP_TRACK_NAME, 1/ABP_ECG_SRATE_HZ))
    return isAbpSegmentValidNumpy(samples, debug)
In [36]:
def saveCaseSegments(caseid, positiveSegments, negativeSegments, compresslevel=9, debug=False, forceWrite=False):
    if len(positiveSegments) == 0 and len(negativeSegments) == 0:
        # exit early if no events found
        print(f'{caseid}: exit early, no segments to save')
        return

    # event composition
    # predictiveSegmentStart in seconds, predictiveSegmentEnd in seconds, predWindow (0 for negative), abp, ecg, eeg)
    # 0start, 1end, 2predwindow, 3abp, 4ecg, 5eeg

    seg_folder = f"{VITAL_EXTRACTED_SEGMENTS}/{caseid:04d}"
    if not os.path.exists(seg_folder):
        # if directory needs to be created, then there are no cached segments
        os.mkdir(seg_folder)
    else:
        if not forceWrite:
            # exit early if folder already exists, case already produced
            return

    # prior to writing files out, clear existing files
    for filename in os.listdir(seg_folder):
        file_path = os.path.join(seg_folder, filename)
        if debug:
            print(f'deleting: {file_path}')
        try:
            if os.path.isfile(file_path):
                os.unlink(file_path)
        except Exception as e:
            print('Failed to delete %s. Reason: %s' % (file_path, e))
    
    count_pos_saved = 0
    for i in range(0, len(positiveSegments)):
        event = positiveSegments[i]
        startIndex = event[0]
        endIndex = event[1]
        predWindow = event[2]
        abp = event[3]
        #ecg = event[4]
        #eeg = event[5]

        seg_filename = f"{caseid:04d}_{startIndex}_{predWindow:02d}_True.h5"
        seg_fullpath = f"{seg_folder}/{seg_filename}"
        if isAbpSegmentValidNumpy(abp, debug):
            count_pos_saved += 1

            abp = abp.tolist()
            ecg = event[4].tolist()
            eeg = event[5].tolist()
        
            f = h5py.File(seg_fullpath, "w")
            f.create_dataset('abp', data=abp, compression="gzip", compression_opts=compresslevel)
            f.create_dataset('ecg', data=ecg, compression="gzip", compression_opts=compresslevel)
            f.create_dataset('eeg', data=eeg, compression="gzip", compression_opts=compresslevel)
            
            f.flush()
            f.close()
            f = None

            abp = None
            ecg = None
            eeg = None

            # f.create_dataset('label', data=[1], compression="gzip", compression_opts=compresslevel)
            # f.create_dataset('pred_window', data=[event[2]], compression="gzip", compression_opts=compresslevel)
            # f.create_dataset('caseid', data=[caseid], compression="gzip", compression_opts=compresslevel)
        elif debug:
            print(f"{caseid:04d} {predWindow:02d}min {startIndex} starttime = ignored, segment validity issues")

    count_neg_saved = 0
    for i in range(0, len(negativeSegments)):
        event = negativeSegments[i]
        startIndex = event[0]
        endIndex = event[1]
        predWindow = event[2]
        abp = event[3]
        #ecg = event[4]
        #eeg = event[5]

        seg_filename = f"{caseid:04d}_{startIndex}_0_False.h5"
        seg_fullpath = f"{seg_folder}/{seg_filename}"
        if isAbpSegmentValidNumpy(abp, debug):
            count_neg_saved += 1

            abp = abp.tolist()
            ecg = event[4].tolist()
            eeg = event[5].tolist()
            
            f = h5py.File(seg_fullpath, "w")
            f.create_dataset('abp', data=abp, compression="gzip", compression_opts=compresslevel)
            f.create_dataset('ecg', data=ecg, compression="gzip", compression_opts=compresslevel)
            f.create_dataset('eeg', data=eeg, compression="gzip", compression_opts=compresslevel)
            
            f.flush()
            f.close()
            f = None

            abp = None
            ecg = None
            eeg = None

            # f.create_dataset('label', data=[0], compression="gzip", compression_opts=compresslevel)
            # f.create_dataset('pred_window', data=[0], compression="gzip", compression_opts=compresslevel)
            # f.create_dataset('caseid', data=[caseid], compression="gzip", compression_opts=compresslevel)
        elif debug:
            print(f"{caseid:04d} CleanWindow {startIndex} starttime = ignored, segment validity issues")
            
    if count_neg_saved == 0 and count_pos_saved == 0:
        print(f'{caseid}: nothing saved, all segments filtered')
In [37]:
# Generate hypotensive events
# Hypotensive events are defined as a 1-minute interval with sustained ABP of less than 65 mmHg
# Note: Hypotensive events should be at least 20 minutes apart to minimize potential residual effects from previous events
# Generate hypotension non-events
# To sample non-events, 30-minute segments where the ABP was above 75 mmHG were selected, and then
# three one-minute samples of each waveform were obtained from the middle of the segment
# both occur in extract_segments
#VITAL_EXTRACTED_SEGMENTS
def extract_segments(
    cases_of_interest_idx,
    debug=False,
    checkCache=True,
    forceWrite=False,
    returnSegments=False,
    skipInvalidCleanEvents=False,
    skipInvalidIohEvents=False
):
    # Sampling rate for ABP and ECG, Hz. These rates should be the same. Default = 500
    ABP_ECG_SRATE_HZ = 500

    # Sampling rate for EEG. Default = 128
    EEG_SRATE_HZ = 128

    # Final dataset for training and testing the model.
    positiveSegmentsMap = {}
    negativeSegmentsMap = {}
    iohEventsMap = {}
    cleanEventsMap = {}

    # Process each case and extract segments. For each segment identify presence of an event in the label zone.
    count_cases = len(cases_of_interest_idx)

    #for case_count, caseid in tqdm(enumerate(cases_of_interest_idx), total=count_cases):
    for case_count, caseid in enumerate(cases_of_interest_idx):
        if debug:
            print(f'Loading case: {caseid:04d}, ({case_count + 1} of {count_cases})')

        if checkCache and areCaseSegmentsCached(caseid):
            if debug:
                print(f'Skipping case: {caseid:04d}, already cached')
            # skip records we've already cached
            continue

        # read the arterial waveform
        (abp, ecg, eeg, event) = get_track_data(caseid)
        if debug:
            print(f'Length of {TRACK_NAMES[0]}:       {abp.shape[0]}')
            print(f'Length of {TRACK_NAMES[1]}:    {ecg.shape[0]}')
            print(f'Length of {TRACK_NAMES[2]}:     {eeg.shape[0]}')

        (startInSeconds, endInSeconds) = getSurgeryBoundariesInSeconds(event)
        if debug:
            print(f"Event markers indicate that surgery begins at {startInSeconds}s and ends at {endInSeconds}s.")

        track_length_seconds = int(len(abp) / ABP_ECG_SRATE_HZ)
        if debug:
            print(f"Processing case {caseid} with length {track_length_seconds}s")

        
        # check if the ABP segment in the surgery window is valid
        if debug:
            isSurgerySegmentValid = isAbpSegmentValidNumpy(abp[startInSeconds:endInSeconds])
            print(f'{caseid}: surgery segment valid: {isSurgerySegmentValid}')
        
        iohEvents = []
        cleanEvents = []
        i = 0
        started = False
        eofReached = False
        trackStartIndex = None

        # set i pointer (which operates in seconds) to start marker for surgery
        i = startInSeconds

        # FIRST PASS
        # in the first forward pass, we are going to identify the start/end boundaries of all IOH events within the case
        ioh_events_valid = []
        
        while i < track_length_seconds - 60 and i < endInSeconds:
            segmentStart = None
            segmentEnd = None
            segFound = False

            # look forward one minute
            abpSeg = abp[i * ABP_ECG_SRATE_HZ:(i + 60) * ABP_ECG_SRATE_HZ]

            # roll forward until we hit a one minute window where mean ABP >= 65 so we know leads are connected and it's tracking
            if not started:
                if np.nanmean(abpSeg) >= 65:
                    started = True
                    trackStartIndex = i
            # if we're started and mean abp for the window is <65, we are starting a new IOH event
            elif np.nanmean(abpSeg) < 65:
                segmentStart = i
                # now seek forward to find end of event, perpetually checking the lats minute of the IOH event
                for j in range(i + 60, track_length_seconds):
                    # look backward one minute
                    abpSegForward = abp[(j - 60) * ABP_ECG_SRATE_HZ:j * ABP_ECG_SRATE_HZ]
                    if np.nanmean(abpSegForward) >= 65:
                        segmentEnd = j - 1
                        break
                if segmentEnd is None:
                    eofReached = True
                else:
                    # otherwise, end of the IOH segment has been reached, record it
                    iohEvents.append((segmentStart, segmentEnd))
                    segFound = True
                    
                    if skipInvalidIohEvents:
                        isIohSegmentValid = isAbpSegmentValidNumpy(abpSeg)
                        ioh_events_valid.append(isIohSegmentValid)
                        if debug:
                            print(f'{caseid}: ioh segment valid: {isIohSegmentValid}, {segmentStart}, {segmentEnd}, {t_abp.shape}')
                    else:
                        ioh_events_valid.append(True)

            i += 1
            if not started:
                continue
            elif eofReached:
                break
            elif segFound:
                i = segmentEnd + 1

        # SECOND PASS
        # in the second forward pass, we are going to identify the start/end boundaries of all non-overlapping 30 minute "clean" windows
        # reuse the 'start of signal' index from our first pass
        if trackStartIndex is None:
            trackStartIndex = startInSeconds
        i = trackStartIndex
        eofReached = False

        clean_events_valid = []
        
        while i < track_length_seconds - 1800 and i < endInSeconds:
            segmentStart = None
            segmentEnd = None
            segFound = False

            startIndex = i
            endIndex = i + 1800

            # check to see if this 30 minute window overlaps any IOH events, if so ffwd to end of latest overlapping IOH
            overlapFound = False
            latestEnd = None
            for event in iohEvents:
                # case 1: starts during an event
                if startIndex >= event[0] and startIndex < event[1]:
                    latestEnd = event[1]
                    overlapFound = True
                # case 2: ends during an event
                elif endIndex >= event[0] and endIndex < event[1]:
                    latestEnd = event[1]
                    overlapFound = True
                # case 3: event occurs entirely inside of the window
                elif startIndex < event[0] and endIndex > event[1]:
                    latestEnd = event[1]
                    overlapFound = True

            # FFWD if we found an overlap
            if overlapFound:
                i = latestEnd + 1
                continue

            # look forward 30 minutes
            abpSeg = abp[startIndex * ABP_ECG_SRATE_HZ:endIndex * ABP_ECG_SRATE_HZ]

            # if we're started and mean abp for the window is >= 75, we are starting a new clean event
            if np.nanmean(abpSeg) >= 75:
                overlapFound = False
                latestEnd = None
                for event in iohEvents:
                    # case 1: starts during an event
                    if startIndex >= event[0] and startIndex < event[1]:
                        latestEnd = event[1]
                        overlapFound = True
                    # case 2: ends during an event
                    elif endIndex >= event[0] and endIndex < event[1]:
                        latestEnd = event[1]
                        overlapFound = True
                    # case 3: event occurs entirely inside of the window
                    elif startIndex < event[0] and endIndex > event[1]:
                        latestEnd = event[1]
                        overlapFound = True

                if not overlapFound:
                    segFound = True
                    segmentEnd = endIndex
                    cleanEvents.append((startIndex, endIndex))
                    
                    if skipInvalidCleanEvents:
                        isCleanSegmentValid = isAbpSegmentValidNumpy(abpSeg)
                        clean_events_valid.append(isCleanSegmentValid)
                        if debug:
                            print(f'{caseid}: clean segment valid: {isCleanSegmentValid}, {startIndex}, {endIndex}, {abpSeg.shape}')
                    else:
                        clean_events_valid.append(True)

            i += 10
            if segFound:
                i = segmentEnd + 1

        if debug:
            print(f"IOH Events for case {caseid}: {iohEvents}")
            print(f"Clean Events for case {caseid}: {cleanEvents}")

        positiveSegments = []
        negativeSegments = []

        # THIRD PASS
        # in the third pass, we will use the collections of ioh event windows to generate our actual extracted segments based on our prediction window (positive labels)
        for i in range(0, len(iohEvents)):
            # Don't extract segments from invalid IOH event windows.
            if not ioh_events_valid[i]:
                continue

            if debug:
                print(f"Checking event {iohEvents[i]}")
            # we want to review current event boundaries, as well as previous event boundaries if available
            event = iohEvents[i]
            previousEvent = None
            if i > 0:
                previousEvent = iohEvents[i - 1]

            for predWindow in ALL_PREDICTION_WINDOWS:
                if debug:
                    print(f"Checking event {iohEvents[i]} for pred {predWindow}")
                iohEventStart = event[0]
                predictiveSegmentEnd = event[0] - (predWindow*60)
                predictiveSegmentStart = predictiveSegmentEnd - 60

                if (predictiveSegmentStart < 0):
                    # don't rewind before the beginning of the track
                    if debug:
                        print(f"Checking event {iohEvents[i]} for pred {predWindow} - exit, before beginning")
                    continue
                elif (predictiveSegmentStart < trackStartIndex):
                    # don't rewind before the beginning of signal in track
                    if debug:
                        print(f"Checking event {iohEvents[i]} for pred {predWindow} - exit, before track start")
                    continue
                elif previousEvent is not None:
                    # does this event window come before or during the previous event?
                    overlapFound = False
                    # case 1: starts during an event
                    if predictiveSegmentStart >= previousEvent[0] and predictiveSegmentStart < previousEvent[1]:
                        overlapFound = True
                    # case 2: ends during an event
                    elif iohEventStart >= previousEvent[0] and iohEventStart < previousEvent[1]:
                        overlapFound = True
                    # case 3: event occurs entirely inside of the window
                    elif predictiveSegmentStart < previousEvent[0] and iohEventStart > previousEvent[1]:
                        overlapFound = True
                    # do not extract a case if we overlap witha nother IOH
                    if overlapFound:
                        if debug:
                            print(f"Checking event {iohEvents[i]} for pred {predWindow} - exit, overlap with earlier segment")
                        continue

                # track the positive segment
                positiveSegments.append((predictiveSegmentStart, predictiveSegmentEnd, predWindow,
                    abp[predictiveSegmentStart*ABP_ECG_SRATE_HZ:predictiveSegmentEnd*ABP_ECG_SRATE_HZ],
                    ecg[predictiveSegmentStart*ABP_ECG_SRATE_HZ:predictiveSegmentEnd*ABP_ECG_SRATE_HZ],
                    eeg[predictiveSegmentStart*EEG_SRATE_HZ:predictiveSegmentEnd*EEG_SRATE_HZ]))

        # FOURTH PASS
        # in the fourth and final pass, we will use the collections of clean event windows to generate our actual extracted segments based (negative labels)
        for i in range(0, len(cleanEvents)):
            # Don't extract segments from invalid clean event windows.
            if not clean_events_valid[i]:
                continue
            
            # everything will be 30 minutes long at least
            event = cleanEvents[i]
            # choose sample 1 @ 10 minutes
            # choose sample 2 @ 15 minutes
            # choose sample 3 @ 20 minutes
            timeAtTen = event[0] + 600
            timeAtFifteen = event[0] + 900
            timeAtTwenty = event[0] + 1200

            negativeSegments.append((timeAtTen, timeAtTen + 60, 0,
                                   abp[timeAtTen*ABP_ECG_SRATE_HZ:(timeAtTen + 60)*ABP_ECG_SRATE_HZ],
                                   ecg[timeAtTen*ABP_ECG_SRATE_HZ:(timeAtTen + 60)*ABP_ECG_SRATE_HZ],
                                   eeg[timeAtTen*EEG_SRATE_HZ:(timeAtTen + 60)*EEG_SRATE_HZ]))
            negativeSegments.append((timeAtFifteen, timeAtFifteen + 60, 0,
                                   abp[timeAtFifteen*ABP_ECG_SRATE_HZ:(timeAtFifteen + 60)*ABP_ECG_SRATE_HZ],
                                   ecg[timeAtFifteen*ABP_ECG_SRATE_HZ:(timeAtFifteen + 60)*ABP_ECG_SRATE_HZ],
                                   eeg[timeAtFifteen*EEG_SRATE_HZ:(timeAtFifteen + 60)*EEG_SRATE_HZ]))
            negativeSegments.append((timeAtTwenty, timeAtTwenty + 60, 0,
                                   abp[timeAtTwenty*ABP_ECG_SRATE_HZ:(timeAtTwenty + 60)*ABP_ECG_SRATE_HZ],
                                   ecg[timeAtTwenty*ABP_ECG_SRATE_HZ:(timeAtTwenty + 60)*ABP_ECG_SRATE_HZ],
                                   eeg[timeAtTwenty*EEG_SRATE_HZ:(timeAtTwenty + 60)*EEG_SRATE_HZ]))

        if returnSegments:
            positiveSegmentsMap[caseid] = positiveSegments
            negativeSegmentsMap[caseid] = negativeSegments
            iohEventsMap[caseid] = iohEvents
            cleanEventsMap[caseid] = cleanEvents
        
        saveCaseSegments(caseid, positiveSegments, negativeSegments, 9, debug=debug, forceWrite=forceWrite)

        #if debug:
        print(f'{caseid}: positiveSegments: {len(positiveSegments)}, negativeSegments: {len(negativeSegments)}')

    return positiveSegmentsMap, negativeSegmentsMap, iohEventsMap, cleanEventsMap

Case Extraction - Generage Segments Needed For Training¶

Ensure that all needed segments are in place for the cases that are being used. If data is already stored on disk this method returns immediately.

In [38]:
print('Time to extract segments!')
Time to extract segments!
In [39]:
MANUAL_EXTRACT=True
SKIP_INVALID_CLEAN_EVENTS=True
SKIP_INVALID_IOH_EVENTS=True

if MANUAL_EXTRACT:
    mycoi = cases_of_interest_idx
    #mycoi = cases_of_interest_idx[:2800]
    #mycoi = [1]

    cnt = 0
    mod = 0
    for ci in mycoi:
        cnt += 1
        if mod % 100 == 0:
            print(f'count processed: {mod}, current case index: {ci}')
        try:
            p, n, i, c = extract_segments([ci], debug=False, checkCache=True, 
                                          forceWrite=True, returnSegments=False, 
                                          skipInvalidCleanEvents=SKIP_INVALID_CLEAN_EVENTS,
                                          skipInvalidIohEvents=SKIP_INVALID_IOH_EVENTS)
            p = None
            n = None
            i = None
            c = None
        except:
            print(f'error on extract segment: {ci}')
        mod += 1
    print(f'extracted: {cnt}')
count processed: 0, current case index: 1
1: positiveSegments: 8, negativeSegments: 3
4: positiveSegments: 22, negativeSegments: 3
7: positiveSegments: 8, negativeSegments: 6
10: positiveSegments: 20, negativeSegments: 6
12: positiveSegments: 22, negativeSegments: 0
13: positiveSegments: 8, negativeSegments: 0
16: positiveSegments: 8, negativeSegments: 6
19: positiveSegments: 33, negativeSegments: 3
20: positiveSegments: 8, negativeSegments: 6
22: positiveSegments: 8, negativeSegments: 12
24: positiveSegments: 0, negativeSegments: 3
25: positiveSegments: 1, negativeSegments: 12
26: exit early, no segments to save
26: positiveSegments: 0, negativeSegments: 0
27: positiveSegments: 8, negativeSegments: 12
29: positiveSegments: 4, negativeSegments: 12
31: positiveSegments: 0, negativeSegments: 3
34: positiveSegments: 0, negativeSegments: 9
38: positiveSegments: 6, negativeSegments: 0
43: positiveSegments: 14, negativeSegments: 3
44: positiveSegments: 0, negativeSegments: 6
46: positiveSegments: 0, negativeSegments: 6
49: exit early, no segments to save
49: positiveSegments: 0, negativeSegments: 0
50: positiveSegments: 10, negativeSegments: 6
52: positiveSegments: 12, negativeSegments: 3
53: positiveSegments: 0, negativeSegments: 9
55: positiveSegments: 15, negativeSegments: 3
58: positiveSegments: 12, negativeSegments: 0
59: positiveSegments: 2, negativeSegments: 0
60: positiveSegments: 4, negativeSegments: 3
61: positiveSegments: 8, negativeSegments: 3
64: positiveSegments: 7, negativeSegments: 9
65: positiveSegments: 0, negativeSegments: 3
66: positiveSegments: 8, negativeSegments: 6
67: positiveSegments: 4, negativeSegments: 0
68: positiveSegments: 0, negativeSegments: 3
69: positiveSegments: 0, negativeSegments: 3
70: positiveSegments: 0, negativeSegments: 6
74: positiveSegments: 0, negativeSegments: 6
75: positiveSegments: 38, negativeSegments: 6
77: positiveSegments: 0, negativeSegments: 9
79: positiveSegments: 12, negativeSegments: 12
83: positiveSegments: 12, negativeSegments: 0
84: positiveSegments: 4, negativeSegments: 15
87: positiveSegments: 9, negativeSegments: 0
89: positiveSegments: 0, negativeSegments: 21
92: positiveSegments: 2, negativeSegments: 0
93: positiveSegments: 3, negativeSegments: 0
94: positiveSegments: 18, negativeSegments: 6
96: positiveSegments: 26, negativeSegments: 15
97: positiveSegments: 8, negativeSegments: 0
98: positiveSegments: 3, negativeSegments: 3
101: positiveSegments: 0, negativeSegments: 6
104: positiveSegments: 7, negativeSegments: 0
105: positiveSegments: 18, negativeSegments: 0
108: positiveSegments: 5, negativeSegments: 0
110: positiveSegments: 8, negativeSegments: 0
111: positiveSegments: 7, negativeSegments: 0
112: positiveSegments: 11, negativeSegments: 0
114: positiveSegments: 8, negativeSegments: 9
116: positiveSegments: 12, negativeSegments: 0
117: positiveSegments: 9, negativeSegments: 3
118: positiveSegments: 44, negativeSegments: 0
119: positiveSegments: 0, negativeSegments: 12
124: positiveSegments: 0, negativeSegments: 3
125: positiveSegments: 4, negativeSegments: 6
126: exit early, no segments to save
126: positiveSegments: 0, negativeSegments: 0
128: positiveSegments: 0, negativeSegments: 3
130: positiveSegments: 0, negativeSegments: 9
132: positiveSegments: 0, negativeSegments: 3
135: positiveSegments: 13, negativeSegments: 0
136: positiveSegments: 0, negativeSegments: 9
137: positiveSegments: 3, negativeSegments: 0
138: positiveSegments: 0, negativeSegments: 9
139: exit early, no segments to save
139: positiveSegments: 0, negativeSegments: 0
140: positiveSegments: 0, negativeSegments: 12
142: positiveSegments: 0, negativeSegments: 15
143: positiveSegments: 8, negativeSegments: 3
145: positiveSegments: 0, negativeSegments: 6
146: positiveSegments: 8, negativeSegments: 0
148: positiveSegments: 13, negativeSegments: 0
149: positiveSegments: 4, negativeSegments: 0
152: exit early, no segments to save
152: positiveSegments: 0, negativeSegments: 0
153: positiveSegments: 4, negativeSegments: 0
156: positiveSegments: 9, negativeSegments: 9
161: positiveSegments: 8, negativeSegments: 3
163: positiveSegments: 3, negativeSegments: 0
166: positiveSegments: 14, negativeSegments: 3
167: positiveSegments: 0, negativeSegments: 3
172: exit early, no segments to save
172: positiveSegments: 0, negativeSegments: 0
175: positiveSegments: 0, negativeSegments: 3
177: positiveSegments: 8, negativeSegments: 6
178: positiveSegments: 0, negativeSegments: 12
181: positiveSegments: 4, negativeSegments: 3
183: positiveSegments: 4, negativeSegments: 0
184: positiveSegments: 34, negativeSegments: 12
186: positiveSegments: 0, negativeSegments: 3
190: positiveSegments: 4, negativeSegments: 3
191: positiveSegments: 12, negativeSegments: 0
195: positiveSegments: 13, negativeSegments: 3
197: positiveSegments: 11, negativeSegments: 6
count processed: 100, current case index: 198
198: positiveSegments: 4, negativeSegments: 12
199: exit early, no segments to save
199: positiveSegments: 0, negativeSegments: 0
200: exit early, no segments to save
200: positiveSegments: 0, negativeSegments: 0
202: positiveSegments: 0, negativeSegments: 21
203: exit early, no segments to save
203: positiveSegments: 0, negativeSegments: 0
206: positiveSegments: 4, negativeSegments: 6
208: positiveSegments: 5, negativeSegments: 0
210: positiveSegments: 4, negativeSegments: 6
218: exit early, no segments to save
218: positiveSegments: 0, negativeSegments: 0
221: exit early, no segments to save
221: positiveSegments: 0, negativeSegments: 0
222: positiveSegments: 0, negativeSegments: 3
229: positiveSegments: 0, negativeSegments: 15
232: positiveSegments: 0, negativeSegments: 3
233: positiveSegments: 6, negativeSegments: 0
234: positiveSegments: 0, negativeSegments: 9
236: positiveSegments: 6, negativeSegments: 15
237: positiveSegments: 0, negativeSegments: 9
239: positiveSegments: 0, negativeSegments: 12
241: positiveSegments: 26, negativeSegments: 12
244: positiveSegments: 9, negativeSegments: 0
247: positiveSegments: 0, negativeSegments: 18
250: positiveSegments: 0, negativeSegments: 3
251: positiveSegments: 20, negativeSegments: 0
252: positiveSegments: 10, negativeSegments: 9
256: positiveSegments: 10, negativeSegments: 3
258: exit early, no segments to save
258: positiveSegments: 0, negativeSegments: 0
261: positiveSegments: 4, negativeSegments: 3
263: positiveSegments: 0, negativeSegments: 3
266: positiveSegments: 0, negativeSegments: 12
268: positiveSegments: 0, negativeSegments: 3
269: positiveSegments: 8, negativeSegments: 6
270: positiveSegments: 2, negativeSegments: 0
279: positiveSegments: 0, negativeSegments: 6
281: positiveSegments: 4, negativeSegments: 6
282: positiveSegments: 0, negativeSegments: 6
283: positiveSegments: 4, negativeSegments: 3
286: positiveSegments: 0, negativeSegments: 9
287: positiveSegments: 0, negativeSegments: 6
293: positiveSegments: 0, negativeSegments: 3
295: positiveSegments: 13, negativeSegments: 6
296: positiveSegments: 0, negativeSegments: 6
297: positiveSegments: 0, negativeSegments: 6
300: positiveSegments: 5, negativeSegments: 3
303: positiveSegments: 7, negativeSegments: 9
304: positiveSegments: 3, negativeSegments: 9
306: positiveSegments: 0, negativeSegments: 12
308: positiveSegments: 4, negativeSegments: 6
309: positiveSegments: 7, negativeSegments: 0
312: positiveSegments: 4, negativeSegments: 3
316: positiveSegments: 4, negativeSegments: 0
318: positiveSegments: 5, negativeSegments: 3
319: exit early, no segments to save
319: positiveSegments: 0, negativeSegments: 0
321: positiveSegments: 4, negativeSegments: 9
323: positiveSegments: 5, negativeSegments: 3
327: positiveSegments: 35, negativeSegments: 0
330: positiveSegments: 4, negativeSegments: 6
337: positiveSegments: 2, negativeSegments: 3
338: exit early, no segments to save
338: positiveSegments: 0, negativeSegments: 0
342: positiveSegments: 0, negativeSegments: 6
343: positiveSegments: 0, negativeSegments: 6
345: positiveSegments: 0, negativeSegments: 15
347: exit early, no segments to save
347: positiveSegments: 0, negativeSegments: 0
348: positiveSegments: 8, negativeSegments: 3
349: positiveSegments: 6, negativeSegments: 0
353: positiveSegments: 0, negativeSegments: 12
354: positiveSegments: 21, negativeSegments: 0
355: positiveSegments: 9, negativeSegments: 3
357: positiveSegments: 4, negativeSegments: 3
358: positiveSegments: 4, negativeSegments: 0
359: positiveSegments: 14, negativeSegments: 6
362: positiveSegments: 0, negativeSegments: 12
363: positiveSegments: 12, negativeSegments: 3
367: positiveSegments: 4, negativeSegments: 3
369: positiveSegments: 0, negativeSegments: 9
370: positiveSegments: 3, negativeSegments: 0
371: positiveSegments: 4, negativeSegments: 3
375: positiveSegments: 24, negativeSegments: 0
380: exit early, no segments to save
380: positiveSegments: 0, negativeSegments: 0
382: positiveSegments: 4, negativeSegments: 12
383: positiveSegments: 4, negativeSegments: 0
384: positiveSegments: 8, negativeSegments: 0
387: positiveSegments: 3, negativeSegments: 0
388: positiveSegments: 4, negativeSegments: 6
390: positiveSegments: 9, negativeSegments: 9
397: positiveSegments: 13, negativeSegments: 0
398: positiveSegments: 0, negativeSegments: 6
402: positiveSegments: 0, negativeSegments: 6
404: positiveSegments: 0, negativeSegments: 6
405: exit early, no segments to save
405: positiveSegments: 0, negativeSegments: 0
406: positiveSegments: 4, negativeSegments: 9
408: exit early, no segments to save
408: positiveSegments: 0, negativeSegments: 0
409: positiveSegments: 9, negativeSegments: 0
413: exit early, no segments to save
413: positiveSegments: 0, negativeSegments: 0
415: positiveSegments: 8, negativeSegments: 0
416: positiveSegments: 11, negativeSegments: 0
417: positiveSegments: 9, negativeSegments: 15
418: positiveSegments: 22, negativeSegments: 0
419: positiveSegments: 0, negativeSegments: 6
425: exit early, no segments to save
425: positiveSegments: 0, negativeSegments: 0
427: positiveSegments: 0, negativeSegments: 6
count processed: 200, current case index: 431
431: positiveSegments: 9, negativeSegments: 0
435: positiveSegments: 0, negativeSegments: 6
439: positiveSegments: 7, negativeSegments: 0
440: positiveSegments: 4, negativeSegments: 6
441: exit early, no segments to save
441: positiveSegments: 0, negativeSegments: 0
442: positiveSegments: 3, negativeSegments: 0
445: positiveSegments: 8, negativeSegments: 18
447: positiveSegments: 0, negativeSegments: 3
448: positiveSegments: 0, negativeSegments: 12
449: positiveSegments: 14, negativeSegments: 0
451: positiveSegments: 16, negativeSegments: 3
452: positiveSegments: 9, negativeSegments: 3
455: positiveSegments: 2, negativeSegments: 0
458: positiveSegments: 0, negativeSegments: 3
462: positiveSegments: 6, negativeSegments: 0
466: positiveSegments: 4, negativeSegments: 9
469: positiveSegments: 24, negativeSegments: 3
472: positiveSegments: 8, negativeSegments: 21
474: positiveSegments: 12, negativeSegments: 3
476: positiveSegments: 21, negativeSegments: 3
478: positiveSegments: 4, negativeSegments: 3
481: positiveSegments: 6, negativeSegments: 3
484: positiveSegments: 0, negativeSegments: 6
485: positiveSegments: 4, negativeSegments: 0
486: positiveSegments: 8, negativeSegments: 3
488: positiveSegments: 14, negativeSegments: 0
490: positiveSegments: 5, negativeSegments: 6
492: positiveSegments: 16, negativeSegments: 15
495: exit early, no segments to save
495: positiveSegments: 0, negativeSegments: 0
499: positiveSegments: 28, negativeSegments: 6
505: positiveSegments: 14, negativeSegments: 3
512: positiveSegments: 0, negativeSegments: 18
513: positiveSegments: 0, negativeSegments: 6
516: positiveSegments: 0, negativeSegments: 3
520: positiveSegments: 10, negativeSegments: 6
521: positiveSegments: 12, negativeSegments: 0
526: positiveSegments: 0, negativeSegments: 6
527: positiveSegments: 10, negativeSegments: 0
530: positiveSegments: 0, negativeSegments: 3
531: exit early, no segments to save
531: positiveSegments: 0, negativeSegments: 0
535: positiveSegments: 0, negativeSegments: 3
536: positiveSegments: 0, negativeSegments: 3
537: positiveSegments: 2, negativeSegments: 0
541: exit early, no segments to save
541: positiveSegments: 0, negativeSegments: 0
543: positiveSegments: 5, negativeSegments: 3
544: positiveSegments: 0, negativeSegments: 3
545: positiveSegments: 0, negativeSegments: 3
547: exit early, no segments to save
547: positiveSegments: 0, negativeSegments: 0
550: positiveSegments: 8, negativeSegments: 6
551: positiveSegments: 15, negativeSegments: 3
553: positiveSegments: 18, negativeSegments: 3
559: positiveSegments: 10, negativeSegments: 6
560: positiveSegments: 0, negativeSegments: 3
561: positiveSegments: 2, negativeSegments: 0
562: positiveSegments: 4, negativeSegments: 6
563: exit early, no segments to save
563: positiveSegments: 0, negativeSegments: 0
564: positiveSegments: 7, negativeSegments: 3
566: positiveSegments: 0, negativeSegments: 6
567: positiveSegments: 0, negativeSegments: 9
568: positiveSegments: 26, negativeSegments: 0
570: positiveSegments: 0, negativeSegments: 9
573: positiveSegments: 5, negativeSegments: 6
576: positiveSegments: 0, negativeSegments: 3
577: positiveSegments: 0, negativeSegments: 9
579: exit early, no segments to save
579: positiveSegments: 0, negativeSegments: 0
582: positiveSegments: 0, negativeSegments: 3
584: exit early, no segments to save
584: positiveSegments: 0, negativeSegments: 0
585: positiveSegments: 4, negativeSegments: 3
587: positiveSegments: 12, negativeSegments: 3
590: positiveSegments: 4, negativeSegments: 3
593: positiveSegments: 0, negativeSegments: 6
594: exit early, no segments to save
594: positiveSegments: 0, negativeSegments: 0
599: positiveSegments: 4, negativeSegments: 3
611: positiveSegments: 4, negativeSegments: 9
612: positiveSegments: 0, negativeSegments: 9
616: positiveSegments: 4, negativeSegments: 0
617: positiveSegments: 4, negativeSegments: 3
620: positiveSegments: 0, negativeSegments: 12
621: positiveSegments: 3, negativeSegments: 0
622: positiveSegments: 0, negativeSegments: 3
624: positiveSegments: 4, negativeSegments: 0
627: positiveSegments: 0, negativeSegments: 6
628: positiveSegments: 32, negativeSegments: 0
629: positiveSegments: 28, negativeSegments: 6
631: positiveSegments: 0, negativeSegments: 15
634: positiveSegments: 0, negativeSegments: 6
636: positiveSegments: 0, negativeSegments: 3
637: positiveSegments: 0, negativeSegments: 15
641: positiveSegments: 0, negativeSegments: 3
644: positiveSegments: 4, negativeSegments: 6
645: positiveSegments: 0, negativeSegments: 3
648: positiveSegments: 4, negativeSegments: 0
649: positiveSegments: 17, negativeSegments: 3
650: exit early, no segments to save
650: positiveSegments: 0, negativeSegments: 0
652: positiveSegments: 7, negativeSegments: 3
655: positiveSegments: 0, negativeSegments: 9
657: nothing saved, all segments filtered
657: positiveSegments: 0, negativeSegments: 3
659: positiveSegments: 4, negativeSegments: 6
660: positiveSegments: 0, negativeSegments: 6
663: positiveSegments: 0, negativeSegments: 6
count processed: 300, current case index: 665
665: positiveSegments: 0, negativeSegments: 3
666: positiveSegments: 11, negativeSegments: 12
667: positiveSegments: 0, negativeSegments: 9
671: positiveSegments: 0, negativeSegments: 15
672: positiveSegments: 0, negativeSegments: 6
676: positiveSegments: 5, negativeSegments: 3
679: exit early, no segments to save
679: positiveSegments: 0, negativeSegments: 0
680: positiveSegments: 2, negativeSegments: 0
683: positiveSegments: 0, negativeSegments: 9
684: positiveSegments: 0, negativeSegments: 3
685: positiveSegments: 0, negativeSegments: 9
687: positiveSegments: 4, negativeSegments: 3
689: exit early, no segments to save
689: positiveSegments: 0, negativeSegments: 0
691: positiveSegments: 0, negativeSegments: 12
697: positiveSegments: 8, negativeSegments: 0
698: positiveSegments: 17, negativeSegments: 3
699: positiveSegments: 9, negativeSegments: 3
702: positiveSegments: 12, negativeSegments: 12
703: positiveSegments: 13, negativeSegments: 3
706: positiveSegments: 14, negativeSegments: 0
711: positiveSegments: 0, negativeSegments: 18
716: positiveSegments: 4, negativeSegments: 3
719: positiveSegments: 0, negativeSegments: 15
721: positiveSegments: 9, negativeSegments: 0
722: positiveSegments: 4, negativeSegments: 6
724: exit early, no segments to save
724: positiveSegments: 0, negativeSegments: 0
725: positiveSegments: 11, negativeSegments: 15
726: positiveSegments: 0, negativeSegments: 3
728: positiveSegments: 16, negativeSegments: 15
729: exit early, no segments to save
729: positiveSegments: 0, negativeSegments: 0
730: positiveSegments: 8, negativeSegments: 3
733: positiveSegments: 10, negativeSegments: 0
734: positiveSegments: 0, negativeSegments: 12
737: positiveSegments: 4, negativeSegments: 3
739: positiveSegments: 0, negativeSegments: 3
740: positiveSegments: 4, negativeSegments: 3
742: positiveSegments: 0, negativeSegments: 6
744: positiveSegments: 0, negativeSegments: 3
745: positiveSegments: 0, negativeSegments: 3
746: positiveSegments: 0, negativeSegments: 3
747: exit early, no segments to save
747: positiveSegments: 0, negativeSegments: 0
748: positiveSegments: 10, negativeSegments: 12
749: positiveSegments: 0, negativeSegments: 3
750: positiveSegments: 49, negativeSegments: 12
751: positiveSegments: 0, negativeSegments: 12
752: positiveSegments: 0, negativeSegments: 12
753: positiveSegments: 2, negativeSegments: 0
755: positiveSegments: 7, negativeSegments: 3
756: positiveSegments: 0, negativeSegments: 9
757: positiveSegments: 0, negativeSegments: 6
758: positiveSegments: 10, negativeSegments: 0
761: positiveSegments: 4, negativeSegments: 0
762: positiveSegments: 0, negativeSegments: 9
763: positiveSegments: 13, negativeSegments: 6
764: positiveSegments: 24, negativeSegments: 6
765: positiveSegments: 12, negativeSegments: 12
767: positiveSegments: 0, negativeSegments: 3
768: exit early, no segments to save
768: positiveSegments: 0, negativeSegments: 0
770: positiveSegments: 3, negativeSegments: 0
772: positiveSegments: 0, negativeSegments: 3
773: positiveSegments: 0, negativeSegments: 3
774: positiveSegments: 13, negativeSegments: 3
775: positiveSegments: 14, negativeSegments: 0
776: positiveSegments: 11, negativeSegments: 3
777: positiveSegments: 7, negativeSegments: 3
779: positiveSegments: 4, negativeSegments: 12
781: positiveSegments: 7, negativeSegments: 0
783: positiveSegments: 4, negativeSegments: 0
788: positiveSegments: 0, negativeSegments: 3
792: exit early, no segments to save
792: positiveSegments: 0, negativeSegments: 0
793: positiveSegments: 17, negativeSegments: 0
794: positiveSegments: 9, negativeSegments: 0
795: positiveSegments: 0, negativeSegments: 6
797: exit early, no segments to save
797: positiveSegments: 0, negativeSegments: 0
800: positiveSegments: 10, negativeSegments: 3
802: positiveSegments: 19, negativeSegments: 6
807: positiveSegments: 8, negativeSegments: 6
808: positiveSegments: 10, negativeSegments: 3
810: exit early, no segments to save
810: positiveSegments: 0, negativeSegments: 0
812: positiveSegments: 0, negativeSegments: 3
813: positiveSegments: 8, negativeSegments: 3
814: positiveSegments: 0, negativeSegments: 12
815: positiveSegments: 0, negativeSegments: 15
816: positiveSegments: 0, negativeSegments: 12
818: exit early, no segments to save
818: positiveSegments: 0, negativeSegments: 0
819: positiveSegments: 11, negativeSegments: 0
822: positiveSegments: 4, negativeSegments: 15
825: positiveSegments: 0, negativeSegments: 9
827: positiveSegments: 3, negativeSegments: 0
830: positiveSegments: 0, negativeSegments: 6
831: positiveSegments: 0, negativeSegments: 3
833: positiveSegments: 11, negativeSegments: 3
835: positiveSegments: 0, negativeSegments: 3
841: positiveSegments: 0, negativeSegments: 9
843: positiveSegments: 15, negativeSegments: 9
846: positiveSegments: 14, negativeSegments: 0
847: positiveSegments: 0, negativeSegments: 15
848: exit early, no segments to save
848: positiveSegments: 0, negativeSegments: 0
851: positiveSegments: 22, negativeSegments: 3
852: positiveSegments: 0, negativeSegments: 3
count processed: 400, current case index: 853
853: positiveSegments: 4, negativeSegments: 6
855: positiveSegments: 7, negativeSegments: 3
859: positiveSegments: 4, negativeSegments: 9
860: positiveSegments: 3, negativeSegments: 3
864: positiveSegments: 3, negativeSegments: 0
865: positiveSegments: 0, negativeSegments: 6
866: positiveSegments: 0, negativeSegments: 6
868: positiveSegments: 6, negativeSegments: 0
869: positiveSegments: 8, negativeSegments: 12
870: positiveSegments: 9, negativeSegments: 3
871: positiveSegments: 0, negativeSegments: 9
872: positiveSegments: 0, negativeSegments: 6
876: positiveSegments: 0, negativeSegments: 3
879: positiveSegments: 0, negativeSegments: 3
880: positiveSegments: 8, negativeSegments: 3
881: exit early, no segments to save
881: positiveSegments: 0, negativeSegments: 0
883: positiveSegments: 15, negativeSegments: 6
885: positiveSegments: 3, negativeSegments: 15
886: positiveSegments: 11, negativeSegments: 18
887: positiveSegments: 4, negativeSegments: 3
890: positiveSegments: 4, negativeSegments: 3
892: positiveSegments: 6, negativeSegments: 3
894: positiveSegments: 4, negativeSegments: 0
898: positiveSegments: 0, negativeSegments: 3
907: positiveSegments: 8, negativeSegments: 9
912: positiveSegments: 4, negativeSegments: 3
913: positiveSegments: 0, negativeSegments: 3
916: positiveSegments: 15, negativeSegments: 6
917: exit early, no segments to save
917: positiveSegments: 0, negativeSegments: 0
919: positiveSegments: 0, negativeSegments: 6
922: positiveSegments: 0, negativeSegments: 3
925: exit early, no segments to save
925: positiveSegments: 0, negativeSegments: 0
926: exit early, no segments to save
926: positiveSegments: 0, negativeSegments: 0
931: positiveSegments: 1, negativeSegments: 0
932: positiveSegments: 4, negativeSegments: 3
933: exit early, no segments to save
933: positiveSegments: 0, negativeSegments: 0
936: positiveSegments: 9, negativeSegments: 3
937: positiveSegments: 0, negativeSegments: 15
938: positiveSegments: 7, negativeSegments: 0
939: positiveSegments: 8, negativeSegments: 3
940: positiveSegments: 6, negativeSegments: 0
944: positiveSegments: 12, negativeSegments: 12
945: positiveSegments: 20, negativeSegments: 3
946: positiveSegments: 9, negativeSegments: 0
947: positiveSegments: 0, negativeSegments: 15
948: positiveSegments: 4, negativeSegments: 6
949: positiveSegments: 8, negativeSegments: 3
952: exit early, no segments to save
952: positiveSegments: 0, negativeSegments: 0
954: positiveSegments: 4, negativeSegments: 6
957: positiveSegments: 0, negativeSegments: 9
958: positiveSegments: 7, negativeSegments: 0
959: positiveSegments: 0, negativeSegments: 12
963: positiveSegments: 0, negativeSegments: 12
967: exit early, no segments to save
967: positiveSegments: 0, negativeSegments: 0
969: positiveSegments: 0, negativeSegments: 3
971: positiveSegments: 4, negativeSegments: 9
972: positiveSegments: 7, negativeSegments: 0
973: positiveSegments: 4, negativeSegments: 0
976: positiveSegments: 0, negativeSegments: 15
977: positiveSegments: 0, negativeSegments: 3
979: positiveSegments: 4, negativeSegments: 0
980: positiveSegments: 8, negativeSegments: 18
983: positiveSegments: 0, negativeSegments: 6
984: positiveSegments: 3, negativeSegments: 0
985: positiveSegments: 8, negativeSegments: 6
986: positiveSegments: 0, negativeSegments: 6
988: positiveSegments: 1, negativeSegments: 9
990: positiveSegments: 13, negativeSegments: 0
991: positiveSegments: 10, negativeSegments: 0
992: positiveSegments: 4, negativeSegments: 12
994: positiveSegments: 2, negativeSegments: 0
995: positiveSegments: 8, negativeSegments: 3
1002: positiveSegments: 3, negativeSegments: 6
1003: positiveSegments: 0, negativeSegments: 3
1005: positiveSegments: 3, negativeSegments: 12
1012: positiveSegments: 4, negativeSegments: 9
1013: positiveSegments: 4, negativeSegments: 9
1015: positiveSegments: 1, negativeSegments: 0
1016: positiveSegments: 0, negativeSegments: 6
1017: positiveSegments: 0, negativeSegments: 6
1018: positiveSegments: 12, negativeSegments: 9
1020: positiveSegments: 0, negativeSegments: 6
1022: positiveSegments: 0, negativeSegments: 9
1024: positiveSegments: 2, negativeSegments: 0
1025: positiveSegments: 10, negativeSegments: 15
1026: positiveSegments: 12, negativeSegments: 12
1027: positiveSegments: 11, negativeSegments: 3
1028: positiveSegments: 0, negativeSegments: 3
1029: positiveSegments: 0, negativeSegments: 6
1030: positiveSegments: 0, negativeSegments: 6
1032: positiveSegments: 6, negativeSegments: 0
1033: positiveSegments: 0, negativeSegments: 3
1034: positiveSegments: 0, negativeSegments: 3
1035: positiveSegments: 0, negativeSegments: 9
1037: positiveSegments: 0, negativeSegments: 21
1038: positiveSegments: 0, negativeSegments: 6
1040: positiveSegments: 4, negativeSegments: 3
1041: positiveSegments: 0, negativeSegments: 6
1043: positiveSegments: 0, negativeSegments: 3
1044: positiveSegments: 3, negativeSegments: 9
count processed: 500, current case index: 1046
1046: positiveSegments: 9, negativeSegments: 0
1047: positiveSegments: 0, negativeSegments: 3
1049: positiveSegments: 1, negativeSegments: 6
1050: positiveSegments: 0, negativeSegments: 3
1051: positiveSegments: 0, negativeSegments: 3
1055: positiveSegments: 0, negativeSegments: 3
1056: positiveSegments: 8, negativeSegments: 0
1061: positiveSegments: 0, negativeSegments: 9
1063: positiveSegments: 10, negativeSegments: 3
1065: exit early, no segments to save
1065: positiveSegments: 0, negativeSegments: 0
1069: positiveSegments: 22, negativeSegments: 3
1073: positiveSegments: 8, negativeSegments: 0
1074: positiveSegments: 7, negativeSegments: 0
1076: positiveSegments: 16, negativeSegments: 3
1077: exit early, no segments to save
1077: positiveSegments: 0, negativeSegments: 0
1078: positiveSegments: 3, negativeSegments: 6
1081: positiveSegments: 4, negativeSegments: 0
1083: positiveSegments: 5, negativeSegments: 0
1084: positiveSegments: 0, negativeSegments: 9
1086: positiveSegments: 18, negativeSegments: 6
1087: positiveSegments: 4, negativeSegments: 6
1088: positiveSegments: 0, negativeSegments: 6
1089: positiveSegments: 0, negativeSegments: 3
1090: positiveSegments: 6, negativeSegments: 3
1091: exit early, no segments to save
1091: positiveSegments: 0, negativeSegments: 0
1093: positiveSegments: 4, negativeSegments: 6
1094: positiveSegments: 17, negativeSegments: 15
1095: positiveSegments: 0, negativeSegments: 21
1096: positiveSegments: 0, negativeSegments: 12
1097: positiveSegments: 9, negativeSegments: 3
1098: positiveSegments: 8, negativeSegments: 0
1102: positiveSegments: 6, negativeSegments: 0
1108: positiveSegments: 6, negativeSegments: 3
1109: positiveSegments: 0, negativeSegments: 3
1113: positiveSegments: 8, negativeSegments: 12
1114: positiveSegments: 13, negativeSegments: 0
1115: positiveSegments: 0, negativeSegments: 12
1118: positiveSegments: 8, negativeSegments: 12
1123: positiveSegments: 14, negativeSegments: 6
1124: positiveSegments: 8, negativeSegments: 0
1125: positiveSegments: 4, negativeSegments: 9
1127: positiveSegments: 10, negativeSegments: 3
1131: positiveSegments: 0, negativeSegments: 6
1132: positiveSegments: 20, negativeSegments: 9
1133: exit early, no segments to save
1133: positiveSegments: 0, negativeSegments: 0
1135: positiveSegments: 0, negativeSegments: 6
1138: positiveSegments: 4, negativeSegments: 0
1139: positiveSegments: 0, negativeSegments: 3
1143: positiveSegments: 5, negativeSegments: 0
1144: exit early, no segments to save
1144: positiveSegments: 0, negativeSegments: 0
1145: positiveSegments: 0, negativeSegments: 12
1154: positiveSegments: 0, negativeSegments: 6
1156: exit early, no segments to save
1156: positiveSegments: 0, negativeSegments: 0
1158: positiveSegments: 4, negativeSegments: 0
1159: positiveSegments: 10, negativeSegments: 3
1160: positiveSegments: 11, negativeSegments: 0
1165: positiveSegments: 9, negativeSegments: 0
1166: positiveSegments: 9, negativeSegments: 3
1170: positiveSegments: 0, negativeSegments: 6
1174: positiveSegments: 4, negativeSegments: 0
1176: positiveSegments: 0, negativeSegments: 9
1180: positiveSegments: 8, negativeSegments: 9
1181: positiveSegments: 4, negativeSegments: 0
1182: positiveSegments: 8, negativeSegments: 9
1184: positiveSegments: 8, negativeSegments: 0
1185: positiveSegments: 22, negativeSegments: 6
1186: positiveSegments: 0, negativeSegments: 3
1187: positiveSegments: 0, negativeSegments: 3
1189: positiveSegments: 15, negativeSegments: 0
1190: exit early, no segments to save
1190: positiveSegments: 0, negativeSegments: 0
1191: positiveSegments: 23, negativeSegments: 6
1193: positiveSegments: 10, negativeSegments: 3
1194: positiveSegments: 8, negativeSegments: 3
1196: positiveSegments: 4, negativeSegments: 0
1199: positiveSegments: 4, negativeSegments: 0
1200: positiveSegments: 8, negativeSegments: 6
1201: positiveSegments: 0, negativeSegments: 3
1202: positiveSegments: 0, negativeSegments: 3
1203: exit early, no segments to save
1203: positiveSegments: 0, negativeSegments: 0
1204: positiveSegments: 12, negativeSegments: 3
1205: positiveSegments: 5, negativeSegments: 6
1208: positiveSegments: 6, negativeSegments: 0
1209: positiveSegments: 5, negativeSegments: 0
1212: exit early, no segments to save
1212: positiveSegments: 0, negativeSegments: 0
1213: positiveSegments: 0, negativeSegments: 6
1215: positiveSegments: 17, negativeSegments: 3
1216: positiveSegments: 16, negativeSegments: 21
1217: positiveSegments: 8, negativeSegments: 0
1219: positiveSegments: 4, negativeSegments: 6
1221: positiveSegments: 8, negativeSegments: 9
1222: positiveSegments: 4, negativeSegments: 9
1224: positiveSegments: 4, negativeSegments: 0
1225: positiveSegments: 0, negativeSegments: 3
1228: positiveSegments: 13, negativeSegments: 0
1229: positiveSegments: 12, negativeSegments: 0
1230: positiveSegments: 6, negativeSegments: 15
1231: nothing saved, all segments filtered
1231: positiveSegments: 1, negativeSegments: 0
1232: positiveSegments: 3, negativeSegments: 6
1233: positiveSegments: 4, negativeSegments: 0
1234: positiveSegments: 0, negativeSegments: 6
count processed: 600, current case index: 1236
1236: positiveSegments: 10, negativeSegments: 0
1237: positiveSegments: 4, negativeSegments: 0
1238: exit early, no segments to save
1238: positiveSegments: 0, negativeSegments: 0
1239: positiveSegments: 0, negativeSegments: 9
1240: positiveSegments: 4, negativeSegments: 6
1244: positiveSegments: 8, negativeSegments: 12
1248: positiveSegments: 0, negativeSegments: 12
1249: positiveSegments: 1, negativeSegments: 6
1256: positiveSegments: 0, negativeSegments: 9
1261: positiveSegments: 10, negativeSegments: 9
1263: positiveSegments: 8, negativeSegments: 9
1264: exit early, no segments to save
1264: positiveSegments: 0, negativeSegments: 0
1265: positiveSegments: 0, negativeSegments: 9
1267: positiveSegments: 0, negativeSegments: 9
1268: positiveSegments: 0, negativeSegments: 6
1271: exit early, no segments to save
1271: positiveSegments: 0, negativeSegments: 0
1272: positiveSegments: 10, negativeSegments: 0
1275: positiveSegments: 11, negativeSegments: 3
1277: positiveSegments: 0, negativeSegments: 9
1279: positiveSegments: 0, negativeSegments: 3
1280: positiveSegments: 0, negativeSegments: 3
1283: exit early, no segments to save
1283: positiveSegments: 0, negativeSegments: 0
1285: positiveSegments: 3, negativeSegments: 6
1286: positiveSegments: 25, negativeSegments: 12
1290: positiveSegments: 0, negativeSegments: 6
1291: positiveSegments: 16, negativeSegments: 6
1292: positiveSegments: 14, negativeSegments: 6
1293: positiveSegments: 12, negativeSegments: 0
1294: exit early, no segments to save
1294: positiveSegments: 0, negativeSegments: 0
1297: positiveSegments: 4, negativeSegments: 0
1298: positiveSegments: 0, negativeSegments: 9
1300: positiveSegments: 2, negativeSegments: 0
1301: exit early, no segments to save
1301: positiveSegments: 0, negativeSegments: 0
1302: positiveSegments: 0, negativeSegments: 9
1303: positiveSegments: 0, negativeSegments: 9
1305: positiveSegments: 10, negativeSegments: 0
1307: positiveSegments: 4, negativeSegments: 12
1309: positiveSegments: 0, negativeSegments: 9
1311: positiveSegments: 0, negativeSegments: 6
1313: positiveSegments: 6, negativeSegments: 6
1315: positiveSegments: 4, negativeSegments: 6
1316: positiveSegments: 4, negativeSegments: 3
1317: positiveSegments: 4, negativeSegments: 0
1319: positiveSegments: 4, negativeSegments: 3
1320: positiveSegments: 4, negativeSegments: 0
1321: positiveSegments: 0, negativeSegments: 12
1323: positiveSegments: 3, negativeSegments: 0
1324: positiveSegments: 3, negativeSegments: 9
1325: positiveSegments: 12, negativeSegments: 9
1333: positiveSegments: 0, negativeSegments: 6
1335: positiveSegments: 10, negativeSegments: 9
1339: positiveSegments: 0, negativeSegments: 3
1340: exit early, no segments to save
1340: positiveSegments: 0, negativeSegments: 0
1341: positiveSegments: 0, negativeSegments: 3
1343: positiveSegments: 4, negativeSegments: 3
1344: positiveSegments: 0, negativeSegments: 9
1346: positiveSegments: 0, negativeSegments: 12
1347: positiveSegments: 0, negativeSegments: 9
1350: positiveSegments: 0, negativeSegments: 15
1353: positiveSegments: 4, negativeSegments: 0
1356: positiveSegments: 5, negativeSegments: 0
1358: positiveSegments: 0, negativeSegments: 9
1359: positiveSegments: 18, negativeSegments: 6
1362: positiveSegments: 9, negativeSegments: 0
1364: positiveSegments: 14, negativeSegments: 0
1365: positiveSegments: 8, negativeSegments: 0
1367: positiveSegments: 23, negativeSegments: 3
1368: positiveSegments: 4, negativeSegments: 0
1369: exit early, no segments to save
1369: positiveSegments: 0, negativeSegments: 0
1374: positiveSegments: 16, negativeSegments: 15
1375: positiveSegments: 4, negativeSegments: 3
1376: positiveSegments: 0, negativeSegments: 3
1381: positiveSegments: 8, negativeSegments: 6
1383: positiveSegments: 10, negativeSegments: 9
1386: positiveSegments: 0, negativeSegments: 3
1389: positiveSegments: 0, negativeSegments: 15
1392: exit early, no segments to save
1392: positiveSegments: 0, negativeSegments: 0
1396: positiveSegments: 4, negativeSegments: 9
1397: positiveSegments: 10, negativeSegments: 3
1398: positiveSegments: 0, negativeSegments: 6
1399: positiveSegments: 11, negativeSegments: 3
1402: positiveSegments: 11, negativeSegments: 0
1403: positiveSegments: 18, negativeSegments: 24
1404: positiveSegments: 0, negativeSegments: 3
1407: positiveSegments: 29, negativeSegments: 3
1408: positiveSegments: 0, negativeSegments: 3
1413: exit early, no segments to save
1413: positiveSegments: 0, negativeSegments: 0
1414: positiveSegments: 4, negativeSegments: 0
1415: positiveSegments: 4, negativeSegments: 3
1416: positiveSegments: 18, negativeSegments: 3
1417: positiveSegments: 0, negativeSegments: 3
1421: positiveSegments: 4, negativeSegments: 6
1422: positiveSegments: 0, negativeSegments: 15
1426: positiveSegments: 4, negativeSegments: 6
1428: positiveSegments: 4, negativeSegments: 6
1432: positiveSegments: 13, negativeSegments: 6
1434: positiveSegments: 19, negativeSegments: 3
1436: positiveSegments: 5, negativeSegments: 12
1438: positiveSegments: 7, negativeSegments: 0
1439: exit early, no segments to save
1439: positiveSegments: 0, negativeSegments: 0
count processed: 700, current case index: 1440
1440: exit early, no segments to save
1440: positiveSegments: 0, negativeSegments: 0
1442: positiveSegments: 4, negativeSegments: 12
1444: exit early, no segments to save
1444: positiveSegments: 0, negativeSegments: 0
1446: positiveSegments: 6, negativeSegments: 3
1451: exit early, no segments to save
1451: positiveSegments: 0, negativeSegments: 0
1452: positiveSegments: 0, negativeSegments: 6
1454: positiveSegments: 0, negativeSegments: 18
1456: exit early, no segments to save
1456: positiveSegments: 0, negativeSegments: 0
1458: positiveSegments: 4, negativeSegments: 0
1463: positiveSegments: 0, negativeSegments: 9
1465: positiveSegments: 4, negativeSegments: 3
1468: positiveSegments: 0, negativeSegments: 18
1469: positiveSegments: 28, negativeSegments: 3
1470: positiveSegments: 4, negativeSegments: 0
1471: positiveSegments: 4, negativeSegments: 0
1473: positiveSegments: 0, negativeSegments: 6
1474: positiveSegments: 0, negativeSegments: 6
1475: positiveSegments: 22, negativeSegments: 3
1478: positiveSegments: 4, negativeSegments: 6
1479: positiveSegments: 0, negativeSegments: 6
1482: positiveSegments: 0, negativeSegments: 18
1485: positiveSegments: 22, negativeSegments: 3
1486: positiveSegments: 15, negativeSegments: 6
1487: positiveSegments: 0, negativeSegments: 3
1488: positiveSegments: 4, negativeSegments: 0
1489: positiveSegments: 15, negativeSegments: 3
1490: positiveSegments: 4, negativeSegments: 3
1492: positiveSegments: 38, negativeSegments: 0
1493: positiveSegments: 12, negativeSegments: 9
1496: positiveSegments: 2, negativeSegments: 6
1497: positiveSegments: 7, negativeSegments: 6
1498: positiveSegments: 0, negativeSegments: 6
1500: positiveSegments: 0, negativeSegments: 6
1503: positiveSegments: 4, negativeSegments: 0
1505: exit early, no segments to save
1505: positiveSegments: 0, negativeSegments: 0
1512: positiveSegments: 0, negativeSegments: 3
1515: positiveSegments: 35, negativeSegments: 3
1520: positiveSegments: 8, negativeSegments: 0
1521: positiveSegments: 8, negativeSegments: 9
1522: positiveSegments: 0, negativeSegments: 9
1523: positiveSegments: 8, negativeSegments: 24
1525: positiveSegments: 18, negativeSegments: 3
1526: positiveSegments: 0, negativeSegments: 9
1527: positiveSegments: 0, negativeSegments: 6
1536: positiveSegments: 0, negativeSegments: 3
1537: positiveSegments: 8, negativeSegments: 0
1539: positiveSegments: 4, negativeSegments: 24
1540: positiveSegments: 1, negativeSegments: 0
1541: positiveSegments: 12, negativeSegments: 0
1542: positiveSegments: 8, negativeSegments: 6
1545: positiveSegments: 10, negativeSegments: 3
1546: positiveSegments: 0, negativeSegments: 3
1548: positiveSegments: 0, negativeSegments: 9
1549: positiveSegments: 7, negativeSegments: 6
1552: positiveSegments: 4, negativeSegments: 0
1553: exit early, no segments to save
1553: positiveSegments: 0, negativeSegments: 0
1554: exit early, no segments to save
1554: positiveSegments: 0, negativeSegments: 0
1555: positiveSegments: 0, negativeSegments: 3
1556: positiveSegments: 4, negativeSegments: 18
1558: positiveSegments: 16, negativeSegments: 0
1559: positiveSegments: 8, negativeSegments: 6
1561: positiveSegments: 0, negativeSegments: 3
1562: positiveSegments: 2, negativeSegments: 9
1563: exit early, no segments to save
1563: positiveSegments: 0, negativeSegments: 0
1564: positiveSegments: 27, negativeSegments: 3
1566: positiveSegments: 4, negativeSegments: 6
1567: positiveSegments: 7, negativeSegments: 0
1568: positiveSegments: 8, negativeSegments: 0
1574: positiveSegments: 0, negativeSegments: 9
1575: positiveSegments: 0, negativeSegments: 6
1580: positiveSegments: 9, negativeSegments: 3
1581: positiveSegments: 0, negativeSegments: 6
1583: positiveSegments: 16, negativeSegments: 6
1585: positiveSegments: 0, negativeSegments: 3
1586: positiveSegments: 4, negativeSegments: 12
1590: positiveSegments: 20, negativeSegments: 0
1591: positiveSegments: 7, negativeSegments: 6
1594: positiveSegments: 4, negativeSegments: 0
1595: positiveSegments: 4, negativeSegments: 12
1596: positiveSegments: 0, negativeSegments: 3
1597: positiveSegments: 4, negativeSegments: 15
1599: positiveSegments: 11, negativeSegments: 15
1600: positiveSegments: 4, negativeSegments: 0
1602: positiveSegments: 4, negativeSegments: 18
1605: positiveSegments: 16, negativeSegments: 9
1608: positiveSegments: 2, negativeSegments: 0
1610: positiveSegments: 0, negativeSegments: 3
1611: exit early, no segments to save
1611: positiveSegments: 0, negativeSegments: 0
1612: exit early, no segments to save
1612: positiveSegments: 0, negativeSegments: 0
1613: positiveSegments: 0, negativeSegments: 3
1614: positiveSegments: 0, negativeSegments: 9
1615: positiveSegments: 1, negativeSegments: 12
1616: positiveSegments: 4, negativeSegments: 6
1618: positiveSegments: 4, negativeSegments: 3
1620: positiveSegments: 8, negativeSegments: 0
1623: positiveSegments: 2, negativeSegments: 0
1630: positiveSegments: 12, negativeSegments: 3
1632: positiveSegments: 2, negativeSegments: 0
1633: positiveSegments: 11, negativeSegments: 3
1636: positiveSegments: 4, negativeSegments: 3
count processed: 800, current case index: 1639
1639: positiveSegments: 7, negativeSegments: 0
1641: positiveSegments: 4, negativeSegments: 12
1642: positiveSegments: 8, negativeSegments: 0
1647: positiveSegments: 6, negativeSegments: 3
1648: positiveSegments: 0, negativeSegments: 3
1656: positiveSegments: 0, negativeSegments: 3
1657: positiveSegments: 0, negativeSegments: 15
1658: positiveSegments: 4, negativeSegments: 6
1662: exit early, no segments to save
1662: positiveSegments: 0, negativeSegments: 0
1665: positiveSegments: 8, negativeSegments: 0
1666: positiveSegments: 8, negativeSegments: 9
1668: exit early, no segments to save
1668: positiveSegments: 0, negativeSegments: 0
1671: positiveSegments: 15, negativeSegments: 3
1672: positiveSegments: 0, negativeSegments: 12
1673: positiveSegments: 9, negativeSegments: 0
1674: positiveSegments: 14, negativeSegments: 0
1675: exit early, no segments to save
1675: positiveSegments: 0, negativeSegments: 0
1676: exit early, no segments to save
1676: positiveSegments: 0, negativeSegments: 0
1681: exit early, no segments to save
1681: positiveSegments: 0, negativeSegments: 0
1684: positiveSegments: 4, negativeSegments: 0
1685: positiveSegments: 0, negativeSegments: 3
1687: exit early, no segments to save
1687: positiveSegments: 0, negativeSegments: 0
1688: exit early, no segments to save
1688: positiveSegments: 0, negativeSegments: 0
1689: positiveSegments: 0, negativeSegments: 6
1690: positiveSegments: 4, negativeSegments: 6
1694: positiveSegments: 14, negativeSegments: 3
1695: positiveSegments: 4, negativeSegments: 3
1696: positiveSegments: 0, negativeSegments: 18
1697: exit early, no segments to save
1697: positiveSegments: 0, negativeSegments: 0
1699: positiveSegments: 0, negativeSegments: 3
1700: positiveSegments: 0, negativeSegments: 6
1703: positiveSegments: 13, negativeSegments: 12
1705: positiveSegments: 4, negativeSegments: 12
1706: positiveSegments: 0, negativeSegments: 9
1708: positiveSegments: 4, negativeSegments: 12
1710: positiveSegments: 8, negativeSegments: 3
1714: positiveSegments: 0, negativeSegments: 9
1716: positiveSegments: 16, negativeSegments: 0
1718: positiveSegments: 15, negativeSegments: 3
1719: positiveSegments: 4, negativeSegments: 0
1722: positiveSegments: 0, negativeSegments: 18
1724: positiveSegments: 5, negativeSegments: 3
1726: positiveSegments: 2, negativeSegments: 9
1728: positiveSegments: 0, negativeSegments: 9
1729: positiveSegments: 4, negativeSegments: 12
1730: positiveSegments: 10, negativeSegments: 0
1732: positiveSegments: 0, negativeSegments: 9
1733: positiveSegments: 15, negativeSegments: 0
1735: positiveSegments: 0, negativeSegments: 6
1737: positiveSegments: 4, negativeSegments: 6
1738: positiveSegments: 11, negativeSegments: 0
1743: positiveSegments: 4, negativeSegments: 9
1745: positiveSegments: 23, negativeSegments: 6
1747: positiveSegments: 0, negativeSegments: 6
1748: positiveSegments: 0, negativeSegments: 3
1749: positiveSegments: 0, negativeSegments: 6
1752: positiveSegments: 37, negativeSegments: 3
1753: positiveSegments: 1, negativeSegments: 0
1756: positiveSegments: 0, negativeSegments: 6
1757: positiveSegments: 0, negativeSegments: 6
1759: positiveSegments: 0, negativeSegments: 3
1761: positiveSegments: 3, negativeSegments: 0
1762: positiveSegments: 0, negativeSegments: 12
1763: positiveSegments: 4, negativeSegments: 3
1765: positiveSegments: 4, negativeSegments: 6
1766: positiveSegments: 12, negativeSegments: 0
1768: positiveSegments: 4, negativeSegments: 0
1771: positiveSegments: 6, negativeSegments: 0
1773: positiveSegments: 6, negativeSegments: 0
1775: positiveSegments: 3, negativeSegments: 0
1777: positiveSegments: 0, negativeSegments: 12
1779: positiveSegments: 2, negativeSegments: 12
1783: positiveSegments: 10, negativeSegments: 3
1784: positiveSegments: 7, negativeSegments: 0
1785: positiveSegments: 21, negativeSegments: 0
1793: positiveSegments: 11, negativeSegments: 0
1799: positiveSegments: 33, negativeSegments: 3
1800: positiveSegments: 0, negativeSegments: 3
1802: positiveSegments: 0, negativeSegments: 6
1803: positiveSegments: 39, negativeSegments: 21
1805: positiveSegments: 4, negativeSegments: 0
1809: positiveSegments: 0, negativeSegments: 12
1810: positiveSegments: 0, negativeSegments: 3
1812: positiveSegments: 8, negativeSegments: 0
1814: positiveSegments: 2, negativeSegments: 3
1816: positiveSegments: 18, negativeSegments: 15
1819: positiveSegments: 19, negativeSegments: 0
1820: positiveSegments: 11, negativeSegments: 0
1822: positiveSegments: 9, negativeSegments: 3
1823: positiveSegments: 0, negativeSegments: 3
1825: positiveSegments: 0, negativeSegments: 3
1826: positiveSegments: 3, negativeSegments: 0
1832: positiveSegments: 26, negativeSegments: 3
1833: positiveSegments: 19, negativeSegments: 0
1834: positiveSegments: 6, negativeSegments: 0
1835: positiveSegments: 12, negativeSegments: 0
1836: positiveSegments: 4, negativeSegments: 0
1837: exit early, no segments to save
1837: positiveSegments: 0, negativeSegments: 0
1838: positiveSegments: 10, negativeSegments: 6
1840: positiveSegments: 1, negativeSegments: 3
count processed: 900, current case index: 1843
1843: positiveSegments: 14, negativeSegments: 6
1844: positiveSegments: 8, negativeSegments: 0
1846: positiveSegments: 2, negativeSegments: 0
1848: positiveSegments: 6, negativeSegments: 6
1852: positiveSegments: 13, negativeSegments: 3
1853: positiveSegments: 0, negativeSegments: 9
1854: positiveSegments: 11, negativeSegments: 0
1855: positiveSegments: 24, negativeSegments: 0
1862: positiveSegments: 15, negativeSegments: 9
1864: exit early, no segments to save
1864: positiveSegments: 0, negativeSegments: 0
1865: positiveSegments: 5, negativeSegments: 0
1866: positiveSegments: 4, negativeSegments: 0
1869: positiveSegments: 0, negativeSegments: 3
1872: positiveSegments: 12, negativeSegments: 0
1873: positiveSegments: 8, negativeSegments: 6
1874: positiveSegments: 8, negativeSegments: 3
1875: exit early, no segments to save
1875: positiveSegments: 0, negativeSegments: 0
1876: exit early, no segments to save
1876: positiveSegments: 0, negativeSegments: 0
1882: positiveSegments: 0, negativeSegments: 3
1884: positiveSegments: 12, negativeSegments: 12
1885: positiveSegments: 0, negativeSegments: 3
1886: positiveSegments: 8, negativeSegments: 6
1888: positiveSegments: 0, negativeSegments: 3
1891: positiveSegments: 0, negativeSegments: 9
1892: positiveSegments: 13, negativeSegments: 9
1893: positiveSegments: 18, negativeSegments: 12
1894: positiveSegments: 4, negativeSegments: 3
1896: positiveSegments: 6, negativeSegments: 3
1898: exit early, no segments to save
1898: positiveSegments: 0, negativeSegments: 0
1899: positiveSegments: 0, negativeSegments: 9
1900: positiveSegments: 21, negativeSegments: 3
1901: positiveSegments: 16, negativeSegments: 6
1903: positiveSegments: 16, negativeSegments: 6
1907: exit early, no segments to save
1907: positiveSegments: 0, negativeSegments: 0
1910: positiveSegments: 3, negativeSegments: 0
1912: positiveSegments: 6, negativeSegments: 21
1913: exit early, no segments to save
1913: positiveSegments: 0, negativeSegments: 0
1914: positiveSegments: 10, negativeSegments: 3
1915: positiveSegments: 2, negativeSegments: 0
1916: positiveSegments: 0, negativeSegments: 15
1918: positiveSegments: 4, negativeSegments: 9
1920: positiveSegments: 12, negativeSegments: 3
1922: positiveSegments: 0, negativeSegments: 6
1925: positiveSegments: 0, negativeSegments: 3
1926: positiveSegments: 4, negativeSegments: 0
1928: positiveSegments: 12, negativeSegments: 0
1931: exit early, no segments to save
1931: positiveSegments: 0, negativeSegments: 0
1932: positiveSegments: 26, negativeSegments: 6
1933: exit early, no segments to save
1933: positiveSegments: 0, negativeSegments: 0
1934: positiveSegments: 23, negativeSegments: 0
1935: positiveSegments: 2, negativeSegments: 12
1936: positiveSegments: 44, negativeSegments: 3
1937: positiveSegments: 8, negativeSegments: 9
1938: positiveSegments: 8, negativeSegments: 15
1941: positiveSegments: 24, negativeSegments: 6
1942: positiveSegments: 6, negativeSegments: 0
1943: exit early, no segments to save
1943: positiveSegments: 0, negativeSegments: 0
1944: positiveSegments: 8, negativeSegments: 6
1947: positiveSegments: 0, negativeSegments: 3
1949: positiveSegments: 4, negativeSegments: 6
1950: positiveSegments: 0, negativeSegments: 3
1955: positiveSegments: 6, negativeSegments: 6
1956: positiveSegments: 4, negativeSegments: 3
1957: positiveSegments: 4, negativeSegments: 0
1959: positiveSegments: 9, negativeSegments: 6
1961: positiveSegments: 18, negativeSegments: 12
1963: positiveSegments: 19, negativeSegments: 9
1965: positiveSegments: 10, negativeSegments: 0
1966: positiveSegments: 6, negativeSegments: 0
1969: positiveSegments: 0, negativeSegments: 9
1973: positiveSegments: 0, negativeSegments: 9
1976: positiveSegments: 20, negativeSegments: 12
1978: positiveSegments: 12, negativeSegments: 6
1985: positiveSegments: 4, negativeSegments: 0
1986: exit early, no segments to save
1986: positiveSegments: 0, negativeSegments: 0
1988: positiveSegments: 0, negativeSegments: 6
1993: positiveSegments: 0, negativeSegments: 6
1994: positiveSegments: 2, negativeSegments: 3
1995: positiveSegments: 6, negativeSegments: 0
1996: positiveSegments: 8, negativeSegments: 3
2000: positiveSegments: 0, negativeSegments: 3
2002: positiveSegments: 2, negativeSegments: 6
2004: positiveSegments: 2, negativeSegments: 6
2009: exit early, no segments to save
2009: positiveSegments: 0, negativeSegments: 0
2010: positiveSegments: 0, negativeSegments: 3
2011: positiveSegments: 0, negativeSegments: 18
2012: positiveSegments: 2, negativeSegments: 0
2014: positiveSegments: 0, negativeSegments: 9
2017: positiveSegments: 12, negativeSegments: 0
2018: positiveSegments: 18, negativeSegments: 3
2020: positiveSegments: 7, negativeSegments: 0
2025: positiveSegments: 4, negativeSegments: 0
2026: positiveSegments: 11, negativeSegments: 0
2028: positiveSegments: 0, negativeSegments: 21
2029: positiveSegments: 0, negativeSegments: 9
2034: exit early, no segments to save
2034: positiveSegments: 0, negativeSegments: 0
2040: positiveSegments: 10, negativeSegments: 9
2041: positiveSegments: 2, negativeSegments: 3
2044: positiveSegments: 4, negativeSegments: 9
2046: positiveSegments: 4, negativeSegments: 0
count processed: 1000, current case index: 2049
2049: positiveSegments: 0, negativeSegments: 3
2051: exit early, no segments to save
2051: positiveSegments: 0, negativeSegments: 0
2055: positiveSegments: 8, negativeSegments: 12
2057: positiveSegments: 9, negativeSegments: 0
2058: positiveSegments: 6, negativeSegments: 0
2060: positiveSegments: 0, negativeSegments: 12
2061: positiveSegments: 4, negativeSegments: 0
2062: positiveSegments: 0, negativeSegments: 15
2064: positiveSegments: 16, negativeSegments: 0
2066: positiveSegments: 7, negativeSegments: 6
2067: positiveSegments: 15, negativeSegments: 3
2068: positiveSegments: 10, negativeSegments: 0
2072: positiveSegments: 2, negativeSegments: 6
2074: exit early, no segments to save
2074: positiveSegments: 0, negativeSegments: 0
2075: positiveSegments: 0, negativeSegments: 3
2081: positiveSegments: 2, negativeSegments: 0
2082: positiveSegments: 8, negativeSegments: 9
2086: positiveSegments: 8, negativeSegments: 0
2088: positiveSegments: 0, negativeSegments: 3
2097: positiveSegments: 3, negativeSegments: 0
2098: positiveSegments: 0, negativeSegments: 3
2106: positiveSegments: 0, negativeSegments: 15
2111: exit early, no segments to save
2111: positiveSegments: 0, negativeSegments: 0
2112: positiveSegments: 7, negativeSegments: 0
2114: positiveSegments: 0, negativeSegments: 3
2117: positiveSegments: 0, negativeSegments: 3
2118: positiveSegments: 0, negativeSegments: 12
2121: positiveSegments: 8, negativeSegments: 3
2130: positiveSegments: 0, negativeSegments: 12
2132: positiveSegments: 7, negativeSegments: 0
2133: positiveSegments: 4, negativeSegments: 0
2135: exit early, no segments to save
2135: positiveSegments: 0, negativeSegments: 0
2136: positiveSegments: 21, negativeSegments: 9
2139: positiveSegments: 0, negativeSegments: 6
2142: positiveSegments: 4, negativeSegments: 0
2147: positiveSegments: 5, negativeSegments: 9
2148: positiveSegments: 0, negativeSegments: 6
2149: positiveSegments: 4, negativeSegments: 6
2150: positiveSegments: 0, negativeSegments: 6
2153: positiveSegments: 33, negativeSegments: 12
2154: positiveSegments: 0, negativeSegments: 12
2157: exit early, no segments to save
2157: positiveSegments: 0, negativeSegments: 0
2158: positiveSegments: 0, negativeSegments: 3
2161: positiveSegments: 16, negativeSegments: 3
2162: exit early, no segments to save
2162: positiveSegments: 0, negativeSegments: 0
2163: positiveSegments: 0, negativeSegments: 3
2165: positiveSegments: 14, negativeSegments: 12
2168: positiveSegments: 27, negativeSegments: 3
2169: positiveSegments: 0, negativeSegments: 12
2170: exit early, no segments to save
2170: positiveSegments: 0, negativeSegments: 0
2172: positiveSegments: 0, negativeSegments: 18
2174: positiveSegments: 0, negativeSegments: 3
2175: positiveSegments: 0, negativeSegments: 3
2176: positiveSegments: 8, negativeSegments: 3
2178: exit early, no segments to save
2178: positiveSegments: 0, negativeSegments: 0
2183: positiveSegments: 0, negativeSegments: 9
2185: positiveSegments: 4, negativeSegments: 9
2187: positiveSegments: 2, negativeSegments: 0
2192: positiveSegments: 14, negativeSegments: 9
2194: positiveSegments: 0, negativeSegments: 18
2195: positiveSegments: 4, negativeSegments: 6
2196: positiveSegments: 0, negativeSegments: 3
2197: positiveSegments: 25, negativeSegments: 6
2201: positiveSegments: 16, negativeSegments: 0
2205: positiveSegments: 0, negativeSegments: 3
2206: positiveSegments: 0, negativeSegments: 3
2210: positiveSegments: 8, negativeSegments: 3
2213: positiveSegments: 0, negativeSegments: 3
2214: positiveSegments: 7, negativeSegments: 6
2218: exit early, no segments to save
2218: positiveSegments: 0, negativeSegments: 0
2219: exit early, no segments to save
2219: positiveSegments: 0, negativeSegments: 0
2221: positiveSegments: 4, negativeSegments: 0
2222: positiveSegments: 4, negativeSegments: 0
2223: exit early, no segments to save
2223: positiveSegments: 0, negativeSegments: 0
2224: positiveSegments: 4, negativeSegments: 0
2225: positiveSegments: 8, negativeSegments: 12
2229: positiveSegments: 0, negativeSegments: 6
2231: positiveSegments: 8, negativeSegments: 6
2236: positiveSegments: 11, negativeSegments: 3
2238: positiveSegments: 0, negativeSegments: 21
2241: positiveSegments: 0, negativeSegments: 9
2242: positiveSegments: 0, negativeSegments: 6
2243: positiveSegments: 20, negativeSegments: 3
2244: positiveSegments: 0, negativeSegments: 6
2246: positiveSegments: 4, negativeSegments: 3
2248: positiveSegments: 3, negativeSegments: 3
2249: positiveSegments: 1, negativeSegments: 0
2251: positiveSegments: 2, negativeSegments: 0
2252: positiveSegments: 4, negativeSegments: 9
2253: exit early, no segments to save
2253: positiveSegments: 0, negativeSegments: 0
2255: exit early, no segments to save
2255: positiveSegments: 0, negativeSegments: 0
2258: positiveSegments: 4, negativeSegments: 3
2261: positiveSegments: 7, negativeSegments: 0
2265: positiveSegments: 7, negativeSegments: 0
2267: positiveSegments: 12, negativeSegments: 3
2272: positiveSegments: 15, negativeSegments: 0
2273: positiveSegments: 0, negativeSegments: 12
2275: positiveSegments: 7, negativeSegments: 3
2279: positiveSegments: 8, negativeSegments: 0
2280: positiveSegments: 8, negativeSegments: 6
count processed: 1100, current case index: 2281
2281: exit early, no segments to save
2281: positiveSegments: 0, negativeSegments: 0
2282: positiveSegments: 0, negativeSegments: 3
2283: exit early, no segments to save
2283: positiveSegments: 0, negativeSegments: 0
2284: exit early, no segments to save
2284: positiveSegments: 0, negativeSegments: 0
2291: positiveSegments: 4, negativeSegments: 0
2295: exit early, no segments to save
2295: positiveSegments: 0, negativeSegments: 0
2296: positiveSegments: 0, negativeSegments: 9
2298: positiveSegments: 4, negativeSegments: 3
2299: positiveSegments: 4, negativeSegments: 3
2300: positiveSegments: 4, negativeSegments: 18
2302: positiveSegments: 4, negativeSegments: 9
2304: positiveSegments: 6, negativeSegments: 6
2305: exit early, no segments to save
2305: positiveSegments: 0, negativeSegments: 0
2306: positiveSegments: 5, negativeSegments: 6
2307: positiveSegments: 0, negativeSegments: 12
2309: positiveSegments: 4, negativeSegments: 0
2310: positiveSegments: 0, negativeSegments: 15
2311: positiveSegments: 6, negativeSegments: 0
2313: exit early, no segments to save
2313: positiveSegments: 0, negativeSegments: 0
2315: positiveSegments: 8, negativeSegments: 0
2317: positiveSegments: 4, negativeSegments: 0
2318: positiveSegments: 22, negativeSegments: 0
2319: positiveSegments: 0, negativeSegments: 6
2321: positiveSegments: 4, negativeSegments: 3
2324: positiveSegments: 11, negativeSegments: 3
2325: positiveSegments: 16, negativeSegments: 3
2326: positiveSegments: 26, negativeSegments: 0
2327: positiveSegments: 6, negativeSegments: 0
2331: positiveSegments: 5, negativeSegments: 0
2332: positiveSegments: 16, negativeSegments: 6
2333: positiveSegments: 4, negativeSegments: 6
2334: positiveSegments: 9, negativeSegments: 3
2335: positiveSegments: 4, negativeSegments: 0
2336: positiveSegments: 23, negativeSegments: 12
2337: positiveSegments: 4, negativeSegments: 6
2339: positiveSegments: 4, negativeSegments: 0
2340: positiveSegments: 16, negativeSegments: 0
2341: positiveSegments: 0, negativeSegments: 3
2345: positiveSegments: 4, negativeSegments: 3
2346: positiveSegments: 0, negativeSegments: 3
2348: positiveSegments: 4, negativeSegments: 9
2349: positiveSegments: 13, negativeSegments: 6
2352: positiveSegments: 3, negativeSegments: 15
2353: positiveSegments: 8, negativeSegments: 12
2354: positiveSegments: 0, negativeSegments: 12
2356: positiveSegments: 13, negativeSegments: 0
2357: positiveSegments: 0, negativeSegments: 6
2359: positiveSegments: 4, negativeSegments: 0
2364: exit early, no segments to save
2364: positiveSegments: 0, negativeSegments: 0
2365: positiveSegments: 3, negativeSegments: 0
2371: positiveSegments: 10, negativeSegments: 3
2372: positiveSegments: 0, negativeSegments: 9
2373: positiveSegments: 7, negativeSegments: 6
2375: positiveSegments: 8, negativeSegments: 15
2377: positiveSegments: 9, negativeSegments: 3
2379: exit early, no segments to save
2379: positiveSegments: 0, negativeSegments: 0
2380: positiveSegments: 0, negativeSegments: 12
2382: exit early, no segments to save
2382: positiveSegments: 0, negativeSegments: 0
2383: positiveSegments: 14, negativeSegments: 3
2389: positiveSegments: 12, negativeSegments: 9
2392: positiveSegments: 0, negativeSegments: 9
2393: positiveSegments: 8, negativeSegments: 3
2394: positiveSegments: 0, negativeSegments: 9
2396: positiveSegments: 16, negativeSegments: 0
2401: positiveSegments: 0, negativeSegments: 9
2405: positiveSegments: 8, negativeSegments: 3
2409: exit early, no segments to save
2409: positiveSegments: 0, negativeSegments: 0
2411: positiveSegments: 10, negativeSegments: 0
2412: exit early, no segments to save
2412: positiveSegments: 0, negativeSegments: 0
2413: positiveSegments: 0, negativeSegments: 3
2416: positiveSegments: 4, negativeSegments: 9
2417: positiveSegments: 0, negativeSegments: 3
2419: positiveSegments: 4, negativeSegments: 0
2420: positiveSegments: 0, negativeSegments: 21
2421: positiveSegments: 0, negativeSegments: 9
2422: positiveSegments: 8, negativeSegments: 0
2424: positiveSegments: 6, negativeSegments: 3
2425: positiveSegments: 0, negativeSegments: 6
2427: positiveSegments: 0, negativeSegments: 9
2428: positiveSegments: 4, negativeSegments: 3
2432: positiveSegments: 9, negativeSegments: 0
2433: positiveSegments: 20, negativeSegments: 21
2434: exit early, no segments to save
2434: positiveSegments: 0, negativeSegments: 0
2435: positiveSegments: 0, negativeSegments: 3
2436: positiveSegments: 0, negativeSegments: 3
2438: positiveSegments: 0, negativeSegments: 3
2441: positiveSegments: 10, negativeSegments: 6
2442: positiveSegments: 4, negativeSegments: 0
2443: positiveSegments: 7, negativeSegments: 27
2444: positiveSegments: 4, negativeSegments: 0
2445: positiveSegments: 12, negativeSegments: 3
2447: positiveSegments: 0, negativeSegments: 6
2450: positiveSegments: 0, negativeSegments: 3
2452: positiveSegments: 14, negativeSegments: 0
2453: positiveSegments: 18, negativeSegments: 6
2455: positiveSegments: 0, negativeSegments: 3
2458: positiveSegments: 22, negativeSegments: 9
2460: exit early, no segments to save
2460: positiveSegments: 0, negativeSegments: 0
2462: positiveSegments: 9, negativeSegments: 3
2466: exit early, no segments to save
2466: positiveSegments: 0, negativeSegments: 0
count processed: 1200, current case index: 2469
2469: positiveSegments: 0, negativeSegments: 6
2470: positiveSegments: 22, negativeSegments: 0
2471: positiveSegments: 10, negativeSegments: 0
2472: positiveSegments: 4, negativeSegments: 9
2473: exit early, no segments to save
2473: positiveSegments: 0, negativeSegments: 0
2474: positiveSegments: 0, negativeSegments: 6
2479: exit early, no segments to save
2479: positiveSegments: 0, negativeSegments: 0
2480: positiveSegments: 3, negativeSegments: 9
2481: positiveSegments: 0, negativeSegments: 3
2482: positiveSegments: 0, negativeSegments: 3
2483: positiveSegments: 4, negativeSegments: 0
2485: positiveSegments: 0, negativeSegments: 6
2487: positiveSegments: 24, negativeSegments: 9
2489: positiveSegments: 22, negativeSegments: 6
2493: positiveSegments: 10, negativeSegments: 3
2494: positiveSegments: 19, negativeSegments: 0
2495: positiveSegments: 4, negativeSegments: 9
2496: positiveSegments: 0, negativeSegments: 6
2497: positiveSegments: 9, negativeSegments: 9
2500: exit early, no segments to save
2500: positiveSegments: 0, negativeSegments: 0
2501: positiveSegments: 0, negativeSegments: 18
2503: positiveSegments: 0, negativeSegments: 3
2507: positiveSegments: 0, negativeSegments: 6
2508: positiveSegments: 0, negativeSegments: 9
2509: exit early, no segments to save
2509: positiveSegments: 0, negativeSegments: 0
2510: exit early, no segments to save
2510: positiveSegments: 0, negativeSegments: 0
2511: exit early, no segments to save
2511: positiveSegments: 0, negativeSegments: 0
2516: positiveSegments: 0, negativeSegments: 3
2517: positiveSegments: 8, negativeSegments: 0
2519: positiveSegments: 20, negativeSegments: 3
2521: positiveSegments: 10, negativeSegments: 0
2523: positiveSegments: 6, negativeSegments: 3
2527: positiveSegments: 0, negativeSegments: 6
2528: exit early, no segments to save
2528: positiveSegments: 0, negativeSegments: 0
2532: positiveSegments: 4, negativeSegments: 0
2533: positiveSegments: 4, negativeSegments: 0
2535: positiveSegments: 4, negativeSegments: 0
2537: positiveSegments: 0, negativeSegments: 6
2539: positiveSegments: 3, negativeSegments: 0
2542: exit early, no segments to save
2542: positiveSegments: 0, negativeSegments: 0
2544: positiveSegments: 10, negativeSegments: 12
2547: positiveSegments: 6, negativeSegments: 6
2549: exit early, no segments to save
2549: positiveSegments: 0, negativeSegments: 0
2553: positiveSegments: 7, negativeSegments: 0
2558: positiveSegments: 8, negativeSegments: 3
2559: positiveSegments: 10, negativeSegments: 0
2561: positiveSegments: 0, negativeSegments: 3
2562: positiveSegments: 0, negativeSegments: 6
2566: positiveSegments: 0, negativeSegments: 3
2568: positiveSegments: 2, negativeSegments: 12
2569: exit early, no segments to save
2569: positiveSegments: 0, negativeSegments: 0
2572: exit early, no segments to save
2572: positiveSegments: 0, negativeSegments: 0
2575: exit early, no segments to save
2575: positiveSegments: 0, negativeSegments: 0
2576: exit early, no segments to save
2576: positiveSegments: 0, negativeSegments: 0
2578: positiveSegments: 4, negativeSegments: 6
2580: positiveSegments: 12, negativeSegments: 6
2583: positiveSegments: 4, negativeSegments: 0
2584: positiveSegments: 17, negativeSegments: 9
2585: positiveSegments: 9, negativeSegments: 0
2587: positiveSegments: 8, negativeSegments: 0
2589: positiveSegments: 0, negativeSegments: 6
2590: positiveSegments: 0, negativeSegments: 6
2593: exit early, no segments to save
2593: positiveSegments: 0, negativeSegments: 0
2594: positiveSegments: 6, negativeSegments: 3
2596: positiveSegments: 4, negativeSegments: 3
2597: exit early, no segments to save
2597: positiveSegments: 0, negativeSegments: 0
2601: positiveSegments: 0, negativeSegments: 9
2605: positiveSegments: 1, negativeSegments: 0
2606: positiveSegments: 8, negativeSegments: 9
2607: positiveSegments: 0, negativeSegments: 3
2608: positiveSegments: 6, negativeSegments: 0
2609: positiveSegments: 0, negativeSegments: 3
2611: positiveSegments: 16, negativeSegments: 3
2612: positiveSegments: 2, negativeSegments: 0
2613: positiveSegments: 0, negativeSegments: 6
2616: exit early, no segments to save
2616: positiveSegments: 0, negativeSegments: 0
2618: positiveSegments: 4, negativeSegments: 15
2619: positiveSegments: 9, negativeSegments: 3
2622: positiveSegments: 8, negativeSegments: 3
2624: positiveSegments: 4, negativeSegments: 6
2627: positiveSegments: 6, negativeSegments: 0
2628: positiveSegments: 0, negativeSegments: 12
2630: positiveSegments: 6, negativeSegments: 6
2631: positiveSegments: 3, negativeSegments: 0
2632: positiveSegments: 10, negativeSegments: 0
2637: positiveSegments: 0, negativeSegments: 3
2639: positiveSegments: 4, negativeSegments: 0
2641: positiveSegments: 0, negativeSegments: 6
2644: positiveSegments: 4, negativeSegments: 0
2646: exit early, no segments to save
2646: positiveSegments: 0, negativeSegments: 0
2648: positiveSegments: 8, negativeSegments: 9
2652: positiveSegments: 0, negativeSegments: 15
2654: positiveSegments: 0, negativeSegments: 6
2655: positiveSegments: 0, negativeSegments: 3
2656: positiveSegments: 0, negativeSegments: 12
2657: positiveSegments: 0, negativeSegments: 6
2658: positiveSegments: 4, negativeSegments: 6
2662: positiveSegments: 8, negativeSegments: 18
2663: positiveSegments: 0, negativeSegments: 6
2664: positiveSegments: 0, negativeSegments: 12
count processed: 1300, current case index: 2665
2665: positiveSegments: 0, negativeSegments: 3
2667: positiveSegments: 0, negativeSegments: 9
2670: exit early, no segments to save
2670: positiveSegments: 0, negativeSegments: 0
2671: positiveSegments: 7, negativeSegments: 3
2673: exit early, no segments to save
2673: positiveSegments: 0, negativeSegments: 0
2674: positiveSegments: 8, negativeSegments: 9
2676: positiveSegments: 2, negativeSegments: 0
2678: positiveSegments: 3, negativeSegments: 3
2680: positiveSegments: 9, negativeSegments: 0
2687: positiveSegments: 6, negativeSegments: 0
2688: positiveSegments: 12, negativeSegments: 3
2690: positiveSegments: 4, negativeSegments: 3
2693: positiveSegments: 11, negativeSegments: 6
2695: exit early, no segments to save
2695: positiveSegments: 0, negativeSegments: 0
2697: positiveSegments: 0, negativeSegments: 9
2698: positiveSegments: 0, negativeSegments: 3
2699: positiveSegments: 0, negativeSegments: 9
2700: positiveSegments: 2, negativeSegments: 0
2701: positiveSegments: 0, negativeSegments: 6
2703: positiveSegments: 0, negativeSegments: 15
2705: positiveSegments: 0, negativeSegments: 6
2706: positiveSegments: 32, negativeSegments: 3
2712: positiveSegments: 10, negativeSegments: 3
2713: positiveSegments: 0, negativeSegments: 3
2716: positiveSegments: 0, negativeSegments: 12
2717: positiveSegments: 8, negativeSegments: 0
2722: positiveSegments: 38, negativeSegments: 0
2724: positiveSegments: 4, negativeSegments: 12
2732: exit early, no segments to save
2732: positiveSegments: 0, negativeSegments: 0
2735: positiveSegments: 0, negativeSegments: 3
2736: exit early, no segments to save
2736: positiveSegments: 0, negativeSegments: 0
2738: positiveSegments: 7, negativeSegments: 3
2741: positiveSegments: 10, negativeSegments: 6
2742: positiveSegments: 11, negativeSegments: 3
2744: positiveSegments: 0, negativeSegments: 6
2746: positiveSegments: 4, negativeSegments: 0
2747: positiveSegments: 4, negativeSegments: 6
2749: positiveSegments: 4, negativeSegments: 3
2750: positiveSegments: 0, negativeSegments: 6
2751: positiveSegments: 21, negativeSegments: 6
2755: positiveSegments: 11, negativeSegments: 9
2760: positiveSegments: 0, negativeSegments: 3
2761: positiveSegments: 11, negativeSegments: 0
2762: positiveSegments: 0, negativeSegments: 3
2763: positiveSegments: 3, negativeSegments: 0
2764: positiveSegments: 16, negativeSegments: 6
2765: positiveSegments: 6, negativeSegments: 0
2766: positiveSegments: 0, negativeSegments: 15
2769: positiveSegments: 0, negativeSegments: 9
2771: exit early, no segments to save
2771: positiveSegments: 0, negativeSegments: 0
2774: positiveSegments: 3, negativeSegments: 0
2775: positiveSegments: 16, negativeSegments: 3
2777: positiveSegments: 4, negativeSegments: 3
2778: positiveSegments: 12, negativeSegments: 3
2779: positiveSegments: 4, negativeSegments: 3
2781: positiveSegments: 13, negativeSegments: 9
2783: positiveSegments: 12, negativeSegments: 0
2785: positiveSegments: 20, negativeSegments: 3
2788: exit early, no segments to save
2788: positiveSegments: 0, negativeSegments: 0
2795: positiveSegments: 8, negativeSegments: 6
2799: exit early, no segments to save
2799: positiveSegments: 0, negativeSegments: 0
2800: positiveSegments: 0, negativeSegments: 12
2803: positiveSegments: 2, negativeSegments: 0
2804: positiveSegments: 8, negativeSegments: 9
2806: positiveSegments: 1, negativeSegments: 0
2807: positiveSegments: 4, negativeSegments: 6
2809: positiveSegments: 8, negativeSegments: 3
2814: positiveSegments: 7, negativeSegments: 6
2815: positiveSegments: 15, negativeSegments: 0
2819: positiveSegments: 6, negativeSegments: 0
2820: positiveSegments: 4, negativeSegments: 9
2823: positiveSegments: 9, negativeSegments: 6
2824: positiveSegments: 15, negativeSegments: 9
2827: positiveSegments: 12, negativeSegments: 0
2828: positiveSegments: 20, negativeSegments: 6
2829: positiveSegments: 13, negativeSegments: 3
2830: positiveSegments: 4, negativeSegments: 0
2835: positiveSegments: 18, negativeSegments: 0
2836: positiveSegments: 0, negativeSegments: 12
2837: positiveSegments: 4, negativeSegments: 6
2839: positiveSegments: 3, negativeSegments: 3
2845: positiveSegments: 0, negativeSegments: 3
2847: positiveSegments: 0, negativeSegments: 15
2848: positiveSegments: 0, negativeSegments: 9
2849: positiveSegments: 8, negativeSegments: 3
2850: positiveSegments: 4, negativeSegments: 6
2851: positiveSegments: 20, negativeSegments: 3
2854: positiveSegments: 4, negativeSegments: 3
2858: positiveSegments: 19, negativeSegments: 3
2859: positiveSegments: 3, negativeSegments: 0
2860: positiveSegments: 4, negativeSegments: 18
2861: positiveSegments: 6, negativeSegments: 0
2863: positiveSegments: 0, negativeSegments: 6
2864: positiveSegments: 4, negativeSegments: 0
2868: positiveSegments: 4, negativeSegments: 3
2871: positiveSegments: 0, negativeSegments: 6
2872: positiveSegments: 8, negativeSegments: 6
2876: positiveSegments: 11, negativeSegments: 9
2877: exit early, no segments to save
2877: positiveSegments: 0, negativeSegments: 0
2883: positiveSegments: 4, negativeSegments: 3
count processed: 1400, current case index: 2888
2888: positiveSegments: 0, negativeSegments: 6
2889: positiveSegments: 7, negativeSegments: 0
2890: positiveSegments: 6, negativeSegments: 0
2891: positiveSegments: 6, negativeSegments: 0
2895: positiveSegments: 0, negativeSegments: 3
2900: exit early, no segments to save
2900: positiveSegments: 0, negativeSegments: 0
2903: positiveSegments: 3, negativeSegments: 0
2905: positiveSegments: 4, negativeSegments: 9
2906: exit early, no segments to save
2906: positiveSegments: 0, negativeSegments: 0
2909: exit early, no segments to save
2909: positiveSegments: 0, negativeSegments: 0
2910: positiveSegments: 0, negativeSegments: 3
2911: positiveSegments: 14, negativeSegments: 12
2914: positiveSegments: 0, negativeSegments: 12
2919: exit early, no segments to save
2919: positiveSegments: 0, negativeSegments: 0
2922: positiveSegments: 4, negativeSegments: 0
2924: positiveSegments: 7, negativeSegments: 0
2927: exit early, no segments to save
2927: positiveSegments: 0, negativeSegments: 0
2929: positiveSegments: 10, negativeSegments: 0
2930: positiveSegments: 0, negativeSegments: 6
2931: positiveSegments: 0, negativeSegments: 3
2935: positiveSegments: 16, negativeSegments: 0
2939: positiveSegments: 0, negativeSegments: 15
2940: positiveSegments: 10, negativeSegments: 6
2943: positiveSegments: 0, negativeSegments: 6
2944: positiveSegments: 0, negativeSegments: 6
2945: positiveSegments: 22, negativeSegments: 9
2947: positiveSegments: 23, negativeSegments: 0
2949: positiveSegments: 2, negativeSegments: 0
2952: positiveSegments: 0, negativeSegments: 21
2954: positiveSegments: 0, negativeSegments: 12
2955: positiveSegments: 4, negativeSegments: 3
2956: positiveSegments: 0, negativeSegments: 9
2958: positiveSegments: 0, negativeSegments: 3
2959: positiveSegments: 8, negativeSegments: 12
2960: positiveSegments: 18, negativeSegments: 0
2961: positiveSegments: 12, negativeSegments: 9
2964: positiveSegments: 13, negativeSegments: 0
2966: positiveSegments: 3, negativeSegments: 3
2970: positiveSegments: 0, negativeSegments: 12
2971: positiveSegments: 0, negativeSegments: 6
2972: positiveSegments: 8, negativeSegments: 0
2974: positiveSegments: 4, negativeSegments: 3
2975: positiveSegments: 2, negativeSegments: 9
2977: positiveSegments: 8, negativeSegments: 0
2980: positiveSegments: 0, negativeSegments: 3
2981: positiveSegments: 0, negativeSegments: 12
2982: positiveSegments: 8, negativeSegments: 9
2987: positiveSegments: 0, negativeSegments: 3
2991: positiveSegments: 12, negativeSegments: 3
2992: positiveSegments: 12, negativeSegments: 3
2993: positiveSegments: 16, negativeSegments: 3
2998: positiveSegments: 0, negativeSegments: 3
2999: positiveSegments: 7, negativeSegments: 0
3000: positiveSegments: 12, negativeSegments: 0
3001: positiveSegments: 8, negativeSegments: 3
3003: positiveSegments: 2, negativeSegments: 0
3004: positiveSegments: 0, negativeSegments: 9
3006: positiveSegments: 6, negativeSegments: 0
3009: positiveSegments: 11, negativeSegments: 3
3014: positiveSegments: 12, negativeSegments: 6
3015: exit early, no segments to save
3015: positiveSegments: 0, negativeSegments: 0
3019: positiveSegments: 27, negativeSegments: 0
3020: positiveSegments: 4, negativeSegments: 0
3023: positiveSegments: 6, negativeSegments: 3
3024: positiveSegments: 23, negativeSegments: 3
3027: positiveSegments: 4, negativeSegments: 0
3028: positiveSegments: 14, negativeSegments: 3
3030: positiveSegments: 0, negativeSegments: 6
3034: positiveSegments: 6, negativeSegments: 0
3035: positiveSegments: 8, negativeSegments: 6
3037: positiveSegments: 14, negativeSegments: 12
3039: positiveSegments: 10, negativeSegments: 0
3040: positiveSegments: 8, negativeSegments: 6
3042: positiveSegments: 7, negativeSegments: 3
3044: positiveSegments: 7, negativeSegments: 3
3045: exit early, no segments to save
3045: positiveSegments: 0, negativeSegments: 0
3046: exit early, no segments to save
3046: positiveSegments: 0, negativeSegments: 0
3047: positiveSegments: 10, negativeSegments: 0
3048: positiveSegments: 0, negativeSegments: 9
3050: positiveSegments: 4, negativeSegments: 0
3051: positiveSegments: 9, negativeSegments: 9
3057: positiveSegments: 0, negativeSegments: 3
3058: positiveSegments: 28, negativeSegments: 0
3059: positiveSegments: 0, negativeSegments: 9
3060: positiveSegments: 0, negativeSegments: 6
3065: nothing saved, all segments filtered
3065: positiveSegments: 1, negativeSegments: 0
3070: positiveSegments: 0, negativeSegments: 3
3072: exit early, no segments to save
3072: positiveSegments: 0, negativeSegments: 0
3073: positiveSegments: 0, negativeSegments: 6
3074: positiveSegments: 21, negativeSegments: 6
3075: positiveSegments: 4, negativeSegments: 6
3078: exit early, no segments to save
3078: positiveSegments: 0, negativeSegments: 0
3079: positiveSegments: 8, negativeSegments: 3
3080: exit early, no segments to save
3080: positiveSegments: 0, negativeSegments: 0
3082: positiveSegments: 4, negativeSegments: 6
3085: positiveSegments: 3, negativeSegments: 0
3087: positiveSegments: 8, negativeSegments: 0
3088: positiveSegments: 3, negativeSegments: 0
3090: positiveSegments: 0, negativeSegments: 6
3091: positiveSegments: 3, negativeSegments: 0
count processed: 1500, current case index: 3092
3092: positiveSegments: 0, negativeSegments: 6
3093: positiveSegments: 8, negativeSegments: 15
3094: positiveSegments: 4, negativeSegments: 6
3095: positiveSegments: 4, negativeSegments: 0
3096: positiveSegments: 4, negativeSegments: 3
3097: positiveSegments: 6, negativeSegments: 0
3098: positiveSegments: 0, negativeSegments: 6
3101: positiveSegments: 7, negativeSegments: 0
3102: positiveSegments: 0, negativeSegments: 3
3103: exit early, no segments to save
3103: positiveSegments: 0, negativeSegments: 0
3106: positiveSegments: 0, negativeSegments: 6
3107: positiveSegments: 5, negativeSegments: 3
3108: positiveSegments: 11, negativeSegments: 3
3110: positiveSegments: 0, negativeSegments: 9
3112: positiveSegments: 0, negativeSegments: 3
3113: positiveSegments: 21, negativeSegments: 6
3114: exit early, no segments to save
3114: positiveSegments: 0, negativeSegments: 0
3116: positiveSegments: 8, negativeSegments: 0
3118: positiveSegments: 0, negativeSegments: 12
3120: positiveSegments: 10, negativeSegments: 0
3121: positiveSegments: 0, negativeSegments: 15
3122: positiveSegments: 0, negativeSegments: 3
3125: positiveSegments: 0, negativeSegments: 6
3126: positiveSegments: 5, negativeSegments: 0
3128: exit early, no segments to save
3128: positiveSegments: 0, negativeSegments: 0
3130: positiveSegments: 0, negativeSegments: 9
3133: positiveSegments: 12, negativeSegments: 3
3134: positiveSegments: 12, negativeSegments: 21
3135: positiveSegments: 0, negativeSegments: 3
3136: positiveSegments: 10, negativeSegments: 0
3137: positiveSegments: 0, negativeSegments: 12
3138: positiveSegments: 17, negativeSegments: 0
3141: positiveSegments: 4, negativeSegments: 3
3142: positiveSegments: 12, negativeSegments: 0
3145: positiveSegments: 16, negativeSegments: 12
3146: positiveSegments: 28, negativeSegments: 3
3147: positiveSegments: 11, negativeSegments: 6
3148: positiveSegments: 28, negativeSegments: 12
3149: positiveSegments: 0, negativeSegments: 12
3150: positiveSegments: 0, negativeSegments: 9
3153: positiveSegments: 4, negativeSegments: 0
3154: positiveSegments: 10, negativeSegments: 6
3155: positiveSegments: 10, negativeSegments: 9
3157: positiveSegments: 12, negativeSegments: 0
3159: positiveSegments: 0, negativeSegments: 6
3161: positiveSegments: 11, negativeSegments: 0
3164: positiveSegments: 4, negativeSegments: 12
3165: positiveSegments: 23, negativeSegments: 0
3167: positiveSegments: 0, negativeSegments: 12
3169: positiveSegments: 4, negativeSegments: 0
3170: positiveSegments: 0, negativeSegments: 3
3172: positiveSegments: 0, negativeSegments: 3
3173: positiveSegments: 14, negativeSegments: 3
3175: positiveSegments: 0, negativeSegments: 3
3176: exit early, no segments to save
3176: positiveSegments: 0, negativeSegments: 0
3180: positiveSegments: 4, negativeSegments: 3
3181: positiveSegments: 0, negativeSegments: 12
3184: positiveSegments: 0, negativeSegments: 3
3186: positiveSegments: 4, negativeSegments: 9
3188: positiveSegments: 31, negativeSegments: 0
3189: positiveSegments: 0, negativeSegments: 12
3193: positiveSegments: 14, negativeSegments: 21
3194: positiveSegments: 0, negativeSegments: 18
3196: positiveSegments: 0, negativeSegments: 9
3198: positiveSegments: 2, negativeSegments: 0
3200: exit early, no segments to save
3200: positiveSegments: 0, negativeSegments: 0
3202: positiveSegments: 3, negativeSegments: 0
3203: positiveSegments: 4, negativeSegments: 12
3205: exit early, no segments to save
3205: positiveSegments: 0, negativeSegments: 0
3207: exit early, no segments to save
3207: positiveSegments: 0, negativeSegments: 0
3208: positiveSegments: 0, negativeSegments: 6
3211: positiveSegments: 0, negativeSegments: 6
3216: positiveSegments: 5, negativeSegments: 3
3218: positiveSegments: 0, negativeSegments: 3
3221: positiveSegments: 0, negativeSegments: 3
3222: positiveSegments: 23, negativeSegments: 0
3223: positiveSegments: 0, negativeSegments: 12
3226: exit early, no segments to save
3226: positiveSegments: 0, negativeSegments: 0
3228: positiveSegments: 28, negativeSegments: 6
3229: positiveSegments: 0, negativeSegments: 6
3231: positiveSegments: 4, negativeSegments: 6
3232: positiveSegments: 0, negativeSegments: 9
3233: positiveSegments: 16, negativeSegments: 3
3235: positiveSegments: 7, negativeSegments: 0
3240: positiveSegments: 0, negativeSegments: 6
3243: positiveSegments: 0, negativeSegments: 6
3247: positiveSegments: 27, negativeSegments: 6
3248: positiveSegments: 8, negativeSegments: 0
3249: exit early, no segments to save
3249: positiveSegments: 0, negativeSegments: 0
3250: positiveSegments: 8, negativeSegments: 6
3255: positiveSegments: 24, negativeSegments: 0
3256: positiveSegments: 4, negativeSegments: 6
3260: positiveSegments: 3, negativeSegments: 3
3263: positiveSegments: 4, negativeSegments: 6
3267: positiveSegments: 0, negativeSegments: 18
3270: positiveSegments: 39, negativeSegments: 0
3271: positiveSegments: 8, negativeSegments: 6
3273: positiveSegments: 21, negativeSegments: 0
3275: positiveSegments: 3, negativeSegments: 3
3276: positiveSegments: 4, negativeSegments: 0
count processed: 1600, current case index: 3279
3279: positiveSegments: 19, negativeSegments: 3
3284: positiveSegments: 16, negativeSegments: 6
3286: positiveSegments: 18, negativeSegments: 0
3287: positiveSegments: 0, negativeSegments: 12
3291: positiveSegments: 20, negativeSegments: 6
3293: positiveSegments: 29, negativeSegments: 6
3295: positiveSegments: 8, negativeSegments: 0
3296: exit early, no segments to save
3296: positiveSegments: 0, negativeSegments: 0
3297: positiveSegments: 18, negativeSegments: 3
3299: positiveSegments: 0, negativeSegments: 3
3304: positiveSegments: 4, negativeSegments: 3
3307: positiveSegments: 10, negativeSegments: 6
3309: positiveSegments: 0, negativeSegments: 6
3310: positiveSegments: 24, negativeSegments: 0
3311: positiveSegments: 18, negativeSegments: 12
3312: positiveSegments: 0, negativeSegments: 3
3315: positiveSegments: 0, negativeSegments: 6
3317: positiveSegments: 4, negativeSegments: 6
3318: positiveSegments: 6, negativeSegments: 9
3321: positiveSegments: 4, negativeSegments: 6
3325: positiveSegments: 6, negativeSegments: 6
3327: positiveSegments: 0, negativeSegments: 3
3328: positiveSegments: 6, negativeSegments: 3
3329: positiveSegments: 6, negativeSegments: 0
3330: positiveSegments: 4, negativeSegments: 12
3331: positiveSegments: 12, negativeSegments: 3
3333: positiveSegments: 3, negativeSegments: 3
3334: positiveSegments: 23, negativeSegments: 9
3336: positiveSegments: 6, negativeSegments: 0
3338: positiveSegments: 10, negativeSegments: 3
3340: positiveSegments: 10, negativeSegments: 3
3342: positiveSegments: 0, negativeSegments: 9
3344: positiveSegments: 4, negativeSegments: 3
3345: positiveSegments: 22, negativeSegments: 3
3348: positiveSegments: 20, negativeSegments: 6
3352: positiveSegments: 14, negativeSegments: 6
3355: positiveSegments: 2, negativeSegments: 0
3357: positiveSegments: 2, negativeSegments: 0
3358: positiveSegments: 8, negativeSegments: 12
3359: positiveSegments: 8, negativeSegments: 0
3361: positiveSegments: 0, negativeSegments: 18
3362: positiveSegments: 0, negativeSegments: 3
3363: positiveSegments: 0, negativeSegments: 12
3364: positiveSegments: 3, negativeSegments: 6
3365: exit early, no segments to save
3365: positiveSegments: 0, negativeSegments: 0
3366: exit early, no segments to save
3366: positiveSegments: 0, negativeSegments: 0
3367: positiveSegments: 0, negativeSegments: 3
3369: positiveSegments: 0, negativeSegments: 3
3373: positiveSegments: 25, negativeSegments: 9
3374: positiveSegments: 0, negativeSegments: 3
3375: positiveSegments: 0, negativeSegments: 3
3376: exit early, no segments to save
3376: positiveSegments: 0, negativeSegments: 0
3377: exit early, no segments to save
3377: positiveSegments: 0, negativeSegments: 0
3379: positiveSegments: 0, negativeSegments: 6
3380: positiveSegments: 0, negativeSegments: 9
3381: positiveSegments: 0, negativeSegments: 18
3382: positiveSegments: 11, negativeSegments: 3
3383: positiveSegments: 4, negativeSegments: 6
3385: positiveSegments: 3, negativeSegments: 9
3389: positiveSegments: 4, negativeSegments: 3
3391: exit early, no segments to save
3391: positiveSegments: 0, negativeSegments: 0
3394: positiveSegments: 0, negativeSegments: 12
3396: positiveSegments: 3, negativeSegments: 0
3398: positiveSegments: 0, negativeSegments: 3
3399: positiveSegments: 0, negativeSegments: 3
3401: positiveSegments: 8, negativeSegments: 3
3404: positiveSegments: 4, negativeSegments: 3
3407: exit early, no segments to save
3407: positiveSegments: 0, negativeSegments: 0
3409: positiveSegments: 12, negativeSegments: 3
3412: positiveSegments: 3, negativeSegments: 0
3413: exit early, no segments to save
3413: positiveSegments: 0, negativeSegments: 0
3414: positiveSegments: 0, negativeSegments: 3
3415: positiveSegments: 21, negativeSegments: 3
3418: positiveSegments: 4, negativeSegments: 9
3422: positiveSegments: 0, negativeSegments: 3
3426: exit early, no segments to save
3426: positiveSegments: 0, negativeSegments: 0
3427: positiveSegments: 4, negativeSegments: 0
3428: positiveSegments: 7, negativeSegments: 3
3429: positiveSegments: 11, negativeSegments: 6
3431: positiveSegments: 0, negativeSegments: 6
3434: exit early, no segments to save
3434: positiveSegments: 0, negativeSegments: 0
3435: positiveSegments: 0, negativeSegments: 3
3436: positiveSegments: 0, negativeSegments: 6
3440: positiveSegments: 0, negativeSegments: 6
3441: positiveSegments: 0, negativeSegments: 3
3442: positiveSegments: 14, negativeSegments: 3
3447: positiveSegments: 0, negativeSegments: 3
3449: positiveSegments: 3, negativeSegments: 3
3450: positiveSegments: 0, negativeSegments: 6
3451: positiveSegments: 0, negativeSegments: 12
3453: positiveSegments: 0, negativeSegments: 6
3457: positiveSegments: 9, negativeSegments: 3
3458: positiveSegments: 4, negativeSegments: 0
3460: positiveSegments: 10, negativeSegments: 0
3462: positiveSegments: 7, negativeSegments: 6
3463: positiveSegments: 0, negativeSegments: 9
3464: positiveSegments: 0, negativeSegments: 6
3468: positiveSegments: 0, negativeSegments: 12
3470: positiveSegments: 8, negativeSegments: 0
3472: positiveSegments: 2, negativeSegments: 0
count processed: 1700, current case index: 3475
3475: positiveSegments: 0, negativeSegments: 3
3476: exit early, no segments to save
3476: positiveSegments: 0, negativeSegments: 0
3478: positiveSegments: 3, negativeSegments: 3
3479: positiveSegments: 0, negativeSegments: 3
3481: positiveSegments: 14, negativeSegments: 0
3483: positiveSegments: 20, negativeSegments: 15
3488: positiveSegments: 0, negativeSegments: 6
3492: positiveSegments: 4, negativeSegments: 0
3499: positiveSegments: 0, negativeSegments: 15
3500: exit early, no segments to save
3500: positiveSegments: 0, negativeSegments: 0
3501: positiveSegments: 4, negativeSegments: 3
3502: positiveSegments: 5, negativeSegments: 9
3503: positiveSegments: 0, negativeSegments: 9
3505: positiveSegments: 0, negativeSegments: 6
3506: positiveSegments: 14, negativeSegments: 0
3513: positiveSegments: 0, negativeSegments: 15
3514: positiveSegments: 6, negativeSegments: 0
3515: positiveSegments: 4, negativeSegments: 6
3516: positiveSegments: 6, negativeSegments: 9
3517: positiveSegments: 3, negativeSegments: 0
3518: exit early, no segments to save
3518: positiveSegments: 0, negativeSegments: 0
3521: positiveSegments: 35, negativeSegments: 6
3524: positiveSegments: 26, negativeSegments: 0
3526: positiveSegments: 3, negativeSegments: 3
3527: positiveSegments: 4, negativeSegments: 6
3528: positiveSegments: 0, negativeSegments: 3
3529: exit early, no segments to save
3529: positiveSegments: 0, negativeSegments: 0
3532: positiveSegments: 0, negativeSegments: 3
3533: exit early, no segments to save
3533: positiveSegments: 0, negativeSegments: 0
3535: positiveSegments: 14, negativeSegments: 0
3537: positiveSegments: 0, negativeSegments: 9
3538: exit early, no segments to save
3538: positiveSegments: 0, negativeSegments: 0
3544: positiveSegments: 0, negativeSegments: 6
3545: exit early, no segments to save
3545: positiveSegments: 0, negativeSegments: 0
3546: positiveSegments: 16, negativeSegments: 6
3549: positiveSegments: 18, negativeSegments: 0
3550: positiveSegments: 20, negativeSegments: 3
3555: positiveSegments: 0, negativeSegments: 6
3558: positiveSegments: 0, negativeSegments: 12
3559: positiveSegments: 17, negativeSegments: 9
3560: positiveSegments: 0, negativeSegments: 3
3562: positiveSegments: 0, negativeSegments: 3
3564: positiveSegments: 0, negativeSegments: 3
3565: positiveSegments: 12, negativeSegments: 3
3566: positiveSegments: 26, negativeSegments: 3
3567: positiveSegments: 0, negativeSegments: 6
3568: positiveSegments: 4, negativeSegments: 3
3569: positiveSegments: 6, negativeSegments: 0
3570: positiveSegments: 4, negativeSegments: 0
3571: positiveSegments: 4, negativeSegments: 15
3572: positiveSegments: 24, negativeSegments: 6
3573: positiveSegments: 8, negativeSegments: 3
3576: positiveSegments: 9, negativeSegments: 6
3581: positiveSegments: 4, negativeSegments: 3
3582: positiveSegments: 4, negativeSegments: 6
3585: positiveSegments: 3, negativeSegments: 0
3588: positiveSegments: 26, negativeSegments: 0
3589: positiveSegments: 0, negativeSegments: 3
3593: positiveSegments: 0, negativeSegments: 9
3594: positiveSegments: 0, negativeSegments: 18
3596: positiveSegments: 0, negativeSegments: 3
3602: positiveSegments: 5, negativeSegments: 6
3603: positiveSegments: 4, negativeSegments: 6
3606: positiveSegments: 0, negativeSegments: 12
3607: positiveSegments: 14, negativeSegments: 3
3608: positiveSegments: 4, negativeSegments: 3
3609: positiveSegments: 5, negativeSegments: 0
3611: positiveSegments: 0, negativeSegments: 3
3614: positiveSegments: 6, negativeSegments: 0
3616: positiveSegments: 18, negativeSegments: 0
3618: positiveSegments: 0, negativeSegments: 9
3620: positiveSegments: 4, negativeSegments: 3
3621: positiveSegments: 17, negativeSegments: 6
3623: positiveSegments: 12, negativeSegments: 0
3625: positiveSegments: 26, negativeSegments: 12
3628: positiveSegments: 6, negativeSegments: 3
3629: positiveSegments: 0, negativeSegments: 3
3631: positiveSegments: 23, negativeSegments: 0
3642: positiveSegments: 0, negativeSegments: 6
3648: positiveSegments: 0, negativeSegments: 3
3652: positiveSegments: 4, negativeSegments: 18
3656: positiveSegments: 0, negativeSegments: 21
3658: positiveSegments: 0, negativeSegments: 9
3660: positiveSegments: 7, negativeSegments: 0
3662: positiveSegments: 0, negativeSegments: 6
3663: positiveSegments: 0, negativeSegments: 9
3668: positiveSegments: 0, negativeSegments: 15
3669: positiveSegments: 12, negativeSegments: 0
3672: positiveSegments: 6, negativeSegments: 0
3674: positiveSegments: 0, negativeSegments: 15
3677: positiveSegments: 0, negativeSegments: 6
3678: positiveSegments: 4, negativeSegments: 6
3680: exit early, no segments to save
3680: positiveSegments: 0, negativeSegments: 0
3682: positiveSegments: 7, negativeSegments: 0
3686: positiveSegments: 17, negativeSegments: 6
3687: positiveSegments: 7, negativeSegments: 9
3688: positiveSegments: 2, negativeSegments: 0
3689: positiveSegments: 12, negativeSegments: 3
3690: positiveSegments: 4, negativeSegments: 3
3691: positiveSegments: 0, negativeSegments: 3
count processed: 1800, current case index: 3694
3694: positiveSegments: 12, negativeSegments: 9
3697: positiveSegments: 0, negativeSegments: 9
3699: positiveSegments: 7, negativeSegments: 6
3700: positiveSegments: 14, negativeSegments: 3
3702: positiveSegments: 4, negativeSegments: 9
3703: positiveSegments: 0, negativeSegments: 9
3704: positiveSegments: 3, negativeSegments: 6
3706: positiveSegments: 0, negativeSegments: 18
3709: exit early, no segments to save
3709: positiveSegments: 0, negativeSegments: 0
3710: positiveSegments: 4, negativeSegments: 9
3711: positiveSegments: 17, negativeSegments: 9
3712: positiveSegments: 4, negativeSegments: 6
3713: positiveSegments: 16, negativeSegments: 0
3719: positiveSegments: 6, negativeSegments: 3
3722: positiveSegments: 12, negativeSegments: 6
3723: positiveSegments: 0, negativeSegments: 3
3724: positiveSegments: 3, negativeSegments: 0
3725: positiveSegments: 15, negativeSegments: 3
3727: positiveSegments: 0, negativeSegments: 3
3728: positiveSegments: 10, negativeSegments: 0
3729: positiveSegments: 0, negativeSegments: 9
3730: positiveSegments: 0, negativeSegments: 3
3732: positiveSegments: 0, negativeSegments: 3
3736: exit early, no segments to save
3736: positiveSegments: 0, negativeSegments: 0
3737: positiveSegments: 15, negativeSegments: 6
3739: positiveSegments: 5, negativeSegments: 0
3740: positiveSegments: 0, negativeSegments: 9
3743: positiveSegments: 0, negativeSegments: 9
3744: positiveSegments: 20, negativeSegments: 0
3748: positiveSegments: 2, negativeSegments: 3
3749: positiveSegments: 12, negativeSegments: 12
3750: positiveSegments: 0, negativeSegments: 9
3752: positiveSegments: 0, negativeSegments: 18
3753: positiveSegments: 0, negativeSegments: 24
3757: positiveSegments: 0, negativeSegments: 6
3758: positiveSegments: 6, negativeSegments: 3
3761: positiveSegments: 8, negativeSegments: 3
3763: positiveSegments: 0, negativeSegments: 6
3764: positiveSegments: 0, negativeSegments: 6
3768: positiveSegments: 4, negativeSegments: 9
3774: positiveSegments: 8, negativeSegments: 0
3775: positiveSegments: 12, negativeSegments: 6
3776: positiveSegments: 0, negativeSegments: 3
3777: positiveSegments: 6, negativeSegments: 3
3782: positiveSegments: 4, negativeSegments: 6
3783: positiveSegments: 6, negativeSegments: 0
3784: positiveSegments: 12, negativeSegments: 0
3785: positiveSegments: 22, negativeSegments: 9
3789: positiveSegments: 0, negativeSegments: 6
3791: positiveSegments: 0, negativeSegments: 12
3793: positiveSegments: 0, negativeSegments: 3
3798: positiveSegments: 4, negativeSegments: 15
3799: positiveSegments: 4, negativeSegments: 0
3800: positiveSegments: 21, negativeSegments: 3
3802: positiveSegments: 4, negativeSegments: 0
3803: positiveSegments: 8, negativeSegments: 0
3805: positiveSegments: 7, negativeSegments: 6
3810: positiveSegments: 0, negativeSegments: 3
3812: positiveSegments: 6, negativeSegments: 0
3813: positiveSegments: 4, negativeSegments: 6
3814: positiveSegments: 0, negativeSegments: 6
3816: positiveSegments: 2, negativeSegments: 3
3817: positiveSegments: 2, negativeSegments: 6
3818: positiveSegments: 0, negativeSegments: 15
3819: positiveSegments: 4, negativeSegments: 3
3821: exit early, no segments to save
3821: positiveSegments: 0, negativeSegments: 0
3822: positiveSegments: 13, negativeSegments: 3
3823: positiveSegments: 0, negativeSegments: 9
3824: positiveSegments: 27, negativeSegments: 6
3825: positiveSegments: 8, negativeSegments: 0
3828: positiveSegments: 8, negativeSegments: 3
3831: positiveSegments: 4, negativeSegments: 9
3832: positiveSegments: 0, negativeSegments: 18
3835: positiveSegments: 0, negativeSegments: 9
3836: positiveSegments: 15, negativeSegments: 6
3837: positiveSegments: 4, negativeSegments: 9
3839: positiveSegments: 4, negativeSegments: 0
3840: positiveSegments: 6, negativeSegments: 3
3842: positiveSegments: 12, negativeSegments: 18
3843: positiveSegments: 16, negativeSegments: 6
3844: positiveSegments: 0, negativeSegments: 18
3845: positiveSegments: 4, negativeSegments: 6
3846: positiveSegments: 12, negativeSegments: 9
3848: positiveSegments: 2, negativeSegments: 3
3849: positiveSegments: 1, negativeSegments: 3
3850: positiveSegments: 0, negativeSegments: 15
3854: positiveSegments: 37, negativeSegments: 6
3855: positiveSegments: 0, negativeSegments: 6
3857: positiveSegments: 9, negativeSegments: 3
3858: exit early, no segments to save
3858: positiveSegments: 0, negativeSegments: 0
3859: positiveSegments: 1, negativeSegments: 0
3863: positiveSegments: 8, negativeSegments: 15
3864: positiveSegments: 8, negativeSegments: 3
3868: positiveSegments: 0, negativeSegments: 3
3870: positiveSegments: 15, negativeSegments: 12
3877: positiveSegments: 5, negativeSegments: 6
3878: positiveSegments: 16, negativeSegments: 6
3879: positiveSegments: 16, negativeSegments: 0
3881: exit early, no segments to save
3881: positiveSegments: 0, negativeSegments: 0
3886: positiveSegments: 0, negativeSegments: 3
count processed: 1900, current case index: 3887
3887: positiveSegments: 0, negativeSegments: 3
3888: positiveSegments: 0, negativeSegments: 6
3889: positiveSegments: 0, negativeSegments: 12
3890: positiveSegments: 8, negativeSegments: 0
3891: positiveSegments: 0, negativeSegments: 6
3893: positiveSegments: 7, negativeSegments: 3
3894: positiveSegments: 0, negativeSegments: 3
3895: positiveSegments: 8, negativeSegments: 9
3897: exit early, no segments to save
3897: positiveSegments: 0, negativeSegments: 0
3898: positiveSegments: 8, negativeSegments: 0
3902: positiveSegments: 4, negativeSegments: 6
3904: positiveSegments: 8, negativeSegments: 3
3906: positiveSegments: 4, negativeSegments: 3
3910: positiveSegments: 0, negativeSegments: 3
3912: positiveSegments: 0, negativeSegments: 3
3913: positiveSegments: 14, negativeSegments: 6
3919: positiveSegments: 11, negativeSegments: 3
3922: exit early, no segments to save
3922: positiveSegments: 0, negativeSegments: 0
3925: positiveSegments: 0, negativeSegments: 9
3928: positiveSegments: 4, negativeSegments: 0
3929: positiveSegments: 10, negativeSegments: 3
3930: positiveSegments: 17, negativeSegments: 3
3931: positiveSegments: 9, negativeSegments: 3
3934: positiveSegments: 0, negativeSegments: 3
3935: positiveSegments: 4, negativeSegments: 0
3936: positiveSegments: 8, negativeSegments: 0
3937: positiveSegments: 3, negativeSegments: 0
3938: positiveSegments: 4, negativeSegments: 3
3944: positiveSegments: 5, negativeSegments: 15
3949: positiveSegments: 8, negativeSegments: 6
3950: positiveSegments: 4, negativeSegments: 15
3955: positiveSegments: 16, negativeSegments: 0
3958: positiveSegments: 4, negativeSegments: 6
3962: positiveSegments: 8, negativeSegments: 0
3963: positiveSegments: 0, negativeSegments: 12
3967: positiveSegments: 0, negativeSegments: 9
3968: positiveSegments: 7, negativeSegments: 3
3971: exit early, no segments to save
3971: positiveSegments: 0, negativeSegments: 0
3972: positiveSegments: 0, negativeSegments: 3
3973: positiveSegments: 0, negativeSegments: 12
3974: positiveSegments: 0, negativeSegments: 12
3975: positiveSegments: 4, negativeSegments: 9
3976: positiveSegments: 0, negativeSegments: 18
3978: positiveSegments: 4, negativeSegments: 0
3980: exit early, no segments to save
3980: positiveSegments: 0, negativeSegments: 0
3981: positiveSegments: 4, negativeSegments: 0
3986: positiveSegments: 0, negativeSegments: 3
3987: positiveSegments: 0, negativeSegments: 6
3988: positiveSegments: 8, negativeSegments: 3
3990: exit early, no segments to save
3990: positiveSegments: 0, negativeSegments: 0
3991: positiveSegments: 0, negativeSegments: 15
3992: exit early, no segments to save
3992: positiveSegments: 0, negativeSegments: 0
3993: positiveSegments: 11, negativeSegments: 9
3994: positiveSegments: 0, negativeSegments: 24
3998: positiveSegments: 0, negativeSegments: 18
3999: positiveSegments: 0, negativeSegments: 3
4000: positiveSegments: 5, negativeSegments: 0
4004: positiveSegments: 0, negativeSegments: 6
4005: positiveSegments: 7, negativeSegments: 9
4007: positiveSegments: 4, negativeSegments: 3
4009: positiveSegments: 1, negativeSegments: 0
4010: positiveSegments: 4, negativeSegments: 3
4011: positiveSegments: 0, negativeSegments: 9
4012: positiveSegments: 3, negativeSegments: 3
4013: positiveSegments: 13, negativeSegments: 9
4016: positiveSegments: 2, negativeSegments: 0
4017: positiveSegments: 1, negativeSegments: 3
4020: positiveSegments: 0, negativeSegments: 6
4022: positiveSegments: 3, negativeSegments: 0
4024: positiveSegments: 5, negativeSegments: 0
4026: positiveSegments: 0, negativeSegments: 21
4027: positiveSegments: 0, negativeSegments: 9
4028: positiveSegments: 0, negativeSegments: 6
4030: positiveSegments: 0, negativeSegments: 9
4032: positiveSegments: 4, negativeSegments: 9
4033: positiveSegments: 15, negativeSegments: 0
4034: positiveSegments: 9, negativeSegments: 0
4035: positiveSegments: 4, negativeSegments: 6
4036: positiveSegments: 8, negativeSegments: 9
4037: positiveSegments: 0, negativeSegments: 3
4040: positiveSegments: 12, negativeSegments: 3
4042: positiveSegments: 0, negativeSegments: 9
4043: positiveSegments: 24, negativeSegments: 9
4045: positiveSegments: 12, negativeSegments: 0
4046: positiveSegments: 0, negativeSegments: 3
4047: exit early, no segments to save
4047: positiveSegments: 0, negativeSegments: 0
4048: positiveSegments: 5, negativeSegments: 0
4050: positiveSegments: 0, negativeSegments: 15
4054: positiveSegments: 15, negativeSegments: 6
4060: positiveSegments: 4, negativeSegments: 15
4062: exit early, no segments to save
4062: positiveSegments: 0, negativeSegments: 0
4066: positiveSegments: 17, negativeSegments: 3
4067: positiveSegments: 0, negativeSegments: 3
4069: positiveSegments: 0, negativeSegments: 3
4070: positiveSegments: 15, negativeSegments: 0
4072: positiveSegments: 13, negativeSegments: 0
4073: positiveSegments: 0, negativeSegments: 3
4074: positiveSegments: 0, negativeSegments: 15
4077: exit early, no segments to save
4077: positiveSegments: 0, negativeSegments: 0
4083: positiveSegments: 0, negativeSegments: 3
count processed: 2000, current case index: 4091
4091: positiveSegments: 0, negativeSegments: 15
4093: positiveSegments: 24, negativeSegments: 6
4098: positiveSegments: 4, negativeSegments: 15
4100: positiveSegments: 0, negativeSegments: 3
4101: positiveSegments: 4, negativeSegments: 3
4106: positiveSegments: 4, negativeSegments: 3
4107: positiveSegments: 3, negativeSegments: 0
4109: positiveSegments: 6, negativeSegments: 0
4111: exit early, no segments to save
4111: positiveSegments: 0, negativeSegments: 0
4112: positiveSegments: 4, negativeSegments: 0
4114: positiveSegments: 20, negativeSegments: 6
4115: positiveSegments: 4, negativeSegments: 12
4116: positiveSegments: 4, negativeSegments: 3
4120: positiveSegments: 0, negativeSegments: 3
4122: exit early, no segments to save
4122: positiveSegments: 0, negativeSegments: 0
4127: positiveSegments: 8, negativeSegments: 9
4133: positiveSegments: 0, negativeSegments: 9
4137: positiveSegments: 18, negativeSegments: 3
4140: positiveSegments: 36, negativeSegments: 6
4142: exit early, no segments to save
4142: positiveSegments: 0, negativeSegments: 0
4143: positiveSegments: 22, negativeSegments: 12
4144: positiveSegments: 20, negativeSegments: 0
4146: positiveSegments: 0, negativeSegments: 18
4148: positiveSegments: 0, negativeSegments: 9
4149: positiveSegments: 9, negativeSegments: 0
4150: positiveSegments: 4, negativeSegments: 0
4152: positiveSegments: 4, negativeSegments: 0
4155: positiveSegments: 4, negativeSegments: 3
4162: positiveSegments: 8, negativeSegments: 9
4165: exit early, no segments to save
4165: positiveSegments: 0, negativeSegments: 0
4166: positiveSegments: 22, negativeSegments: 21
4167: positiveSegments: 21, negativeSegments: 0
4168: positiveSegments: 3, negativeSegments: 0
4172: positiveSegments: 4, negativeSegments: 3
4173: positiveSegments: 0, negativeSegments: 3
4177: positiveSegments: 4, negativeSegments: 0
4179: positiveSegments: 21, negativeSegments: 0
4181: positiveSegments: 0, negativeSegments: 6
4183: exit early, no segments to save
4183: positiveSegments: 0, negativeSegments: 0
4186: positiveSegments: 4, negativeSegments: 3
4187: exit early, no segments to save
4187: positiveSegments: 0, negativeSegments: 0
4189: positiveSegments: 4, negativeSegments: 6
4191: positiveSegments: 2, negativeSegments: 15
4195: positiveSegments: 0, negativeSegments: 6
4198: exit early, no segments to save
4198: positiveSegments: 0, negativeSegments: 0
4201: exit early, no segments to save
4201: positiveSegments: 0, negativeSegments: 0
4202: positiveSegments: 4, negativeSegments: 9
4203: exit early, no segments to save
4203: positiveSegments: 0, negativeSegments: 0
4206: positiveSegments: 8, negativeSegments: 0
4207: positiveSegments: 4, negativeSegments: 18
4208: positiveSegments: 7, negativeSegments: 0
4210: positiveSegments: 10, negativeSegments: 3
4211: positiveSegments: 11, negativeSegments: 3
4212: positiveSegments: 0, negativeSegments: 12
4213: positiveSegments: 0, negativeSegments: 3
4214: positiveSegments: 0, negativeSegments: 12
4216: positiveSegments: 0, negativeSegments: 15
4219: exit early, no segments to save
4219: positiveSegments: 0, negativeSegments: 0
4222: positiveSegments: 0, negativeSegments: 9
4223: positiveSegments: 0, negativeSegments: 3
4225: positiveSegments: 17, negativeSegments: 12
4227: positiveSegments: 4, negativeSegments: 3
4233: positiveSegments: 0, negativeSegments: 9
4236: positiveSegments: 8, negativeSegments: 3
4238: positiveSegments: 4, negativeSegments: 9
4240: positiveSegments: 19, negativeSegments: 0
4241: positiveSegments: 0, negativeSegments: 3
4242: positiveSegments: 4, negativeSegments: 3
4245: positiveSegments: 18, negativeSegments: 0
4247: positiveSegments: 0, negativeSegments: 6
4249: positiveSegments: 14, negativeSegments: 3
4251: positiveSegments: 19, negativeSegments: 0
4252: positiveSegments: 0, negativeSegments: 9
4253: exit early, no segments to save
4253: positiveSegments: 0, negativeSegments: 0
4254: positiveSegments: 4, negativeSegments: 6
4255: positiveSegments: 6, negativeSegments: 3
4256: positiveSegments: 43, negativeSegments: 6
4258: positiveSegments: 12, negativeSegments: 3
4259: positiveSegments: 0, negativeSegments: 6
4262: exit early, no segments to save
4262: positiveSegments: 0, negativeSegments: 0
4264: positiveSegments: 8, negativeSegments: 6
4265: positiveSegments: 13, negativeSegments: 0
4268: exit early, no segments to save
4268: positiveSegments: 0, negativeSegments: 0
4269: positiveSegments: 14, negativeSegments: 6
4272: positiveSegments: 17, negativeSegments: 3
4277: exit early, no segments to save
4277: positiveSegments: 0, negativeSegments: 0
4278: positiveSegments: 12, negativeSegments: 3
4279: positiveSegments: 4, negativeSegments: 3
4280: positiveSegments: 8, negativeSegments: 3
4281: positiveSegments: 0, negativeSegments: 3
4282: positiveSegments: 12, negativeSegments: 3
4283: positiveSegments: 16, negativeSegments: 0
4284: positiveSegments: 4, negativeSegments: 9
4286: positiveSegments: 4, negativeSegments: 0
4287: positiveSegments: 0, negativeSegments: 9
4289: positiveSegments: 27, negativeSegments: 6
4290: exit early, no segments to save
4290: positiveSegments: 0, negativeSegments: 0
4292: positiveSegments: 4, negativeSegments: 15
4293: positiveSegments: 2, negativeSegments: 0
4294: positiveSegments: 0, negativeSegments: 9
count processed: 2100, current case index: 4296
4296: positiveSegments: 3, negativeSegments: 6
4302: positiveSegments: 16, negativeSegments: 6
4304: positiveSegments: 28, negativeSegments: 0
4305: positiveSegments: 9, negativeSegments: 0
4307: positiveSegments: 4, negativeSegments: 3
4308: positiveSegments: 0, negativeSegments: 3
4309: positiveSegments: 3, negativeSegments: 3
4310: positiveSegments: 4, negativeSegments: 12
4314: positiveSegments: 0, negativeSegments: 9
4316: positiveSegments: 9, negativeSegments: 3
4317: positiveSegments: 10, negativeSegments: 0
4320: positiveSegments: 6, negativeSegments: 6
4322: positiveSegments: 4, negativeSegments: 9
4325: positiveSegments: 0, negativeSegments: 3
4326: positiveSegments: 8, negativeSegments: 3
4327: positiveSegments: 11, negativeSegments: 0
4328: exit early, no segments to save
4328: positiveSegments: 0, negativeSegments: 0
4332: positiveSegments: 5, negativeSegments: 0
4333: positiveSegments: 12, negativeSegments: 6
4335: positiveSegments: 0, negativeSegments: 15
4339: positiveSegments: 4, negativeSegments: 0
4341: positiveSegments: 4, negativeSegments: 12
4345: positiveSegments: 11, negativeSegments: 0
4347: positiveSegments: 15, negativeSegments: 3
4350: positiveSegments: 0, negativeSegments: 3
4352: exit early, no segments to save
4352: positiveSegments: 0, negativeSegments: 0
4354: positiveSegments: 7, negativeSegments: 6
4356: positiveSegments: 0, negativeSegments: 9
4362: exit early, no segments to save
4362: positiveSegments: 0, negativeSegments: 0
4364: positiveSegments: 4, negativeSegments: 3
4367: positiveSegments: 0, negativeSegments: 9
4368: positiveSegments: 4, negativeSegments: 6
4371: positiveSegments: 0, negativeSegments: 3
4375: positiveSegments: 0, negativeSegments: 15
4377: positiveSegments: 8, negativeSegments: 15
4380: positiveSegments: 4, negativeSegments: 0
4382: positiveSegments: 5, negativeSegments: 3
4383: positiveSegments: 8, negativeSegments: 6
4385: positiveSegments: 0, negativeSegments: 3
4387: exit early, no segments to save
4387: positiveSegments: 0, negativeSegments: 0
4388: positiveSegments: 1, negativeSegments: 0
4389: positiveSegments: 0, negativeSegments: 3
4390: positiveSegments: 11, negativeSegments: 6
4392: positiveSegments: 8, negativeSegments: 3
4396: positiveSegments: 0, negativeSegments: 3
4398: positiveSegments: 14, negativeSegments: 0
4400: positiveSegments: 4, negativeSegments: 6
4401: positiveSegments: 0, negativeSegments: 6
4402: positiveSegments: 4, negativeSegments: 12
4405: positiveSegments: 15, negativeSegments: 0
4406: positiveSegments: 3, negativeSegments: 0
4408: positiveSegments: 4, negativeSegments: 0
4409: positiveSegments: 4, negativeSegments: 9
4411: positiveSegments: 4, negativeSegments: 0
4414: exit early, no segments to save
4414: positiveSegments: 0, negativeSegments: 0
4417: positiveSegments: 4, negativeSegments: 3
4424: positiveSegments: 0, negativeSegments: 12
4425: exit early, no segments to save
4425: positiveSegments: 0, negativeSegments: 0
4426: positiveSegments: 0, negativeSegments: 6
4428: exit early, no segments to save
4428: positiveSegments: 0, negativeSegments: 0
4429: positiveSegments: 14, negativeSegments: 6
4430: positiveSegments: 0, negativeSegments: 9
4432: positiveSegments: 0, negativeSegments: 6
4433: exit early, no segments to save
4433: positiveSegments: 0, negativeSegments: 0
4435: exit early, no segments to save
4435: positiveSegments: 0, negativeSegments: 0
4437: positiveSegments: 7, negativeSegments: 3
4439: positiveSegments: 12, negativeSegments: 0
4443: positiveSegments: 0, negativeSegments: 6
4449: positiveSegments: 0, negativeSegments: 6
4451: positiveSegments: 10, negativeSegments: 6
4453: positiveSegments: 8, negativeSegments: 0
4456: positiveSegments: 4, negativeSegments: 12
4457: positiveSegments: 4, negativeSegments: 9
4458: positiveSegments: 6, negativeSegments: 0
4459: exit early, no segments to save
4459: positiveSegments: 0, negativeSegments: 0
4461: positiveSegments: 8, negativeSegments: 15
4462: positiveSegments: 11, negativeSegments: 0
4463: positiveSegments: 0, negativeSegments: 12
4464: exit early, no segments to save
4464: positiveSegments: 0, negativeSegments: 0
4466: exit early, no segments to save
4466: positiveSegments: 0, negativeSegments: 0
4470: positiveSegments: 0, negativeSegments: 6
4472: positiveSegments: 12, negativeSegments: 0
4474: positiveSegments: 0, negativeSegments: 9
4475: positiveSegments: 0, negativeSegments: 9
4476: positiveSegments: 11, negativeSegments: 3
4477: positiveSegments: 3, negativeSegments: 0
4478: positiveSegments: 0, negativeSegments: 12
4480: positiveSegments: 0, negativeSegments: 3
4481: positiveSegments: 25, negativeSegments: 9
4483: positiveSegments: 0, negativeSegments: 3
4485: positiveSegments: 1, negativeSegments: 0
4489: positiveSegments: 0, negativeSegments: 9
4490: positiveSegments: 6, negativeSegments: 0
4496: positiveSegments: 15, negativeSegments: 9
4497: positiveSegments: 4, negativeSegments: 0
4498: positiveSegments: 0, negativeSegments: 6
4501: exit early, no segments to save
4501: positiveSegments: 0, negativeSegments: 0
4502: positiveSegments: 4, negativeSegments: 3
4503: positiveSegments: 0, negativeSegments: 3
4504: positiveSegments: 39, negativeSegments: 0
count processed: 2200, current case index: 4509
4509: positiveSegments: 4, negativeSegments: 9
4510: positiveSegments: 15, negativeSegments: 3
4515: positiveSegments: 1, negativeSegments: 0
4519: exit early, no segments to save
4519: positiveSegments: 0, negativeSegments: 0
4520: positiveSegments: 0, negativeSegments: 3
4522: positiveSegments: 0, negativeSegments: 3
4525: positiveSegments: 0, negativeSegments: 9
4530: positiveSegments: 0, negativeSegments: 6
4536: positiveSegments: 0, negativeSegments: 3
4538: positiveSegments: 2, negativeSegments: 3
4540: positiveSegments: 0, negativeSegments: 9
4541: positiveSegments: 0, negativeSegments: 3
4546: positiveSegments: 0, negativeSegments: 3
4547: positiveSegments: 0, negativeSegments: 6
4549: positiveSegments: 8, negativeSegments: 3
4550: positiveSegments: 0, negativeSegments: 9
4557: exit early, no segments to save
4557: positiveSegments: 0, negativeSegments: 0
4559: positiveSegments: 7, negativeSegments: 0
4561: positiveSegments: 4, negativeSegments: 0
4564: positiveSegments: 4, negativeSegments: 3
4568: positiveSegments: 12, negativeSegments: 6
4569: positiveSegments: 0, negativeSegments: 3
4572: positiveSegments: 0, negativeSegments: 3
4573: positiveSegments: 34, negativeSegments: 3
4574: positiveSegments: 28, negativeSegments: 12
4576: positiveSegments: 0, negativeSegments: 15
4577: positiveSegments: 0, negativeSegments: 6
4578: positiveSegments: 5, negativeSegments: 0
4579: exit early, no segments to save
4579: positiveSegments: 0, negativeSegments: 0
4581: positiveSegments: 3, negativeSegments: 3
4584: positiveSegments: 0, negativeSegments: 9
4589: positiveSegments: 4, negativeSegments: 9
4591: positiveSegments: 17, negativeSegments: 0
4596: positiveSegments: 0, negativeSegments: 9
4597: positiveSegments: 14, negativeSegments: 0
4599: positiveSegments: 10, negativeSegments: 0
4600: positiveSegments: 11, negativeSegments: 6
4602: positiveSegments: 6, negativeSegments: 0
4603: positiveSegments: 0, negativeSegments: 6
4604: positiveSegments: 15, negativeSegments: 12
4605: positiveSegments: 0, negativeSegments: 3
4607: positiveSegments: 7, negativeSegments: 0
4609: positiveSegments: 0, negativeSegments: 27
4612: positiveSegments: 6, negativeSegments: 6
4613: exit early, no segments to save
4613: positiveSegments: 0, negativeSegments: 0
4616: exit early, no segments to save
4616: positiveSegments: 0, negativeSegments: 0
4617: positiveSegments: 4, negativeSegments: 9
4618: positiveSegments: 10, negativeSegments: 6
4619: positiveSegments: 0, negativeSegments: 6
4620: positiveSegments: 4, negativeSegments: 0
4621: positiveSegments: 6, negativeSegments: 6
4622: exit early, no segments to save
4622: positiveSegments: 0, negativeSegments: 0
4626: positiveSegments: 8, negativeSegments: 3
4627: positiveSegments: 9, negativeSegments: 0
4631: positiveSegments: 0, negativeSegments: 3
4632: positiveSegments: 12, negativeSegments: 6
4635: positiveSegments: 4, negativeSegments: 0
4639: positiveSegments: 6, negativeSegments: 6
4640: exit early, no segments to save
4640: positiveSegments: 0, negativeSegments: 0
4644: positiveSegments: 12, negativeSegments: 15
4646: positiveSegments: 6, negativeSegments: 3
4648: exit early, no segments to save
4648: positiveSegments: 0, negativeSegments: 0
4650: exit early, no segments to save
4650: positiveSegments: 0, negativeSegments: 0
4652: positiveSegments: 19, negativeSegments: 6
4653: positiveSegments: 10, negativeSegments: 3
4654: positiveSegments: 3, negativeSegments: 9
4655: positiveSegments: 3, negativeSegments: 0
4656: positiveSegments: 9, negativeSegments: 0
4657: positiveSegments: 13, negativeSegments: 0
4658: positiveSegments: 1, negativeSegments: 6
4660: positiveSegments: 0, negativeSegments: 6
4662: positiveSegments: 12, negativeSegments: 0
4665: positiveSegments: 15, negativeSegments: 3
4666: positiveSegments: 4, negativeSegments: 15
4670: positiveSegments: 36, negativeSegments: 0
4673: exit early, no segments to save
4673: positiveSegments: 0, negativeSegments: 0
4678: positiveSegments: 0, negativeSegments: 6
4683: positiveSegments: 7, negativeSegments: 0
4684: positiveSegments: 20, negativeSegments: 9
4686: positiveSegments: 8, negativeSegments: 0
4690: exit early, no segments to save
4690: positiveSegments: 0, negativeSegments: 0
4695: positiveSegments: 3, negativeSegments: 0
4700: positiveSegments: 0, negativeSegments: 3
4702: exit early, no segments to save
4702: positiveSegments: 0, negativeSegments: 0
4703: exit early, no segments to save
4703: positiveSegments: 0, negativeSegments: 0
4705: positiveSegments: 3, negativeSegments: 0
4706: positiveSegments: 0, negativeSegments: 9
4711: positiveSegments: 6, negativeSegments: 3
4713: positiveSegments: 0, negativeSegments: 12
4714: exit early, no segments to save
4714: positiveSegments: 0, negativeSegments: 0
4715: positiveSegments: 13, negativeSegments: 9
4716: positiveSegments: 4, negativeSegments: 3
4717: positiveSegments: 0, negativeSegments: 6
4718: positiveSegments: 10, negativeSegments: 3
4721: positiveSegments: 20, negativeSegments: 0
4724: positiveSegments: 0, negativeSegments: 3
4726: positiveSegments: 3, negativeSegments: 3
4727: exit early, no segments to save
4727: positiveSegments: 0, negativeSegments: 0
4729: positiveSegments: 3, negativeSegments: 6
4731: positiveSegments: 4, negativeSegments: 9
count processed: 2300, current case index: 4732
4732: positiveSegments: 0, negativeSegments: 18
4733: exit early, no segments to save
4733: positiveSegments: 0, negativeSegments: 0
4739: positiveSegments: 11, negativeSegments: 0
4741: exit early, no segments to save
4741: positiveSegments: 0, negativeSegments: 0
4743: positiveSegments: 4, negativeSegments: 3
4744: positiveSegments: 6, negativeSegments: 0
4745: positiveSegments: 4, negativeSegments: 9
4746: positiveSegments: 0, negativeSegments: 6
4749: positiveSegments: 16, negativeSegments: 3
4750: positiveSegments: 0, negativeSegments: 12
4752: positiveSegments: 0, negativeSegments: 9
4755: positiveSegments: 4, negativeSegments: 0
4757: positiveSegments: 10, negativeSegments: 15
4759: positiveSegments: 17, negativeSegments: 9
4761: positiveSegments: 3, negativeSegments: 0
4763: positiveSegments: 3, negativeSegments: 0
4764: positiveSegments: 8, negativeSegments: 12
4767: positiveSegments: 2, negativeSegments: 3
4768: positiveSegments: 0, negativeSegments: 3
4769: positiveSegments: 0, negativeSegments: 3
4771: positiveSegments: 2, negativeSegments: 0
4773: positiveSegments: 4, negativeSegments: 6
4775: positiveSegments: 13, negativeSegments: 3
4777: positiveSegments: 10, negativeSegments: 0
4778: positiveSegments: 11, negativeSegments: 0
4779: positiveSegments: 10, negativeSegments: 0
4780: positiveSegments: 7, negativeSegments: 3
4781: positiveSegments: 0, negativeSegments: 21
4783: positiveSegments: 4, negativeSegments: 0
4784: exit early, no segments to save
4784: positiveSegments: 0, negativeSegments: 0
4785: positiveSegments: 0, negativeSegments: 6
4786: positiveSegments: 3, negativeSegments: 0
4788: positiveSegments: 12, negativeSegments: 3
4789: positiveSegments: 3, negativeSegments: 6
4790: positiveSegments: 0, negativeSegments: 3
4792: positiveSegments: 0, negativeSegments: 9
4794: exit early, no segments to save
4794: positiveSegments: 0, negativeSegments: 0
4798: positiveSegments: 0, negativeSegments: 9
4800: positiveSegments: 22, negativeSegments: 3
4801: positiveSegments: 25, negativeSegments: 9
4802: positiveSegments: 9, negativeSegments: 0
4803: positiveSegments: 0, negativeSegments: 3
4805: exit early, no segments to save
4805: positiveSegments: 0, negativeSegments: 0
4806: positiveSegments: 0, negativeSegments: 9
4808: positiveSegments: 4, negativeSegments: 3
4809: positiveSegments: 13, negativeSegments: 6
4813: positiveSegments: 4, negativeSegments: 3
4816: positiveSegments: 12, negativeSegments: 0
4817: positiveSegments: 36, negativeSegments: 3
4818: positiveSegments: 0, negativeSegments: 3
4820: positiveSegments: 14, negativeSegments: 0
4823: positiveSegments: 0, negativeSegments: 6
4825: positiveSegments: 10, negativeSegments: 0
4826: positiveSegments: 4, negativeSegments: 3
4828: positiveSegments: 19, negativeSegments: 0
4830: positiveSegments: 4, negativeSegments: 0
4831: positiveSegments: 8, negativeSegments: 3
4834: exit early, no segments to save
4834: positiveSegments: 0, negativeSegments: 0
4835: positiveSegments: 7, negativeSegments: 6
4836: exit early, no segments to save
4836: positiveSegments: 0, negativeSegments: 0
4837: positiveSegments: 0, negativeSegments: 3
4839: positiveSegments: 10, negativeSegments: 6
4841: positiveSegments: 3, negativeSegments: 0
4843: positiveSegments: 0, negativeSegments: 6
4844: positiveSegments: 0, negativeSegments: 3
4847: positiveSegments: 0, negativeSegments: 3
4851: positiveSegments: 24, negativeSegments: 0
4853: positiveSegments: 7, negativeSegments: 9
4857: positiveSegments: 0, negativeSegments: 3
4858: positiveSegments: 15, negativeSegments: 3
4859: positiveSegments: 0, negativeSegments: 6
4860: exit early, no segments to save
4860: positiveSegments: 0, negativeSegments: 0
4861: positiveSegments: 20, negativeSegments: 0
4865: positiveSegments: 0, negativeSegments: 12
4869: positiveSegments: 10, negativeSegments: 3
4871: positiveSegments: 25, negativeSegments: 3
4872: positiveSegments: 0, negativeSegments: 6
4874: positiveSegments: 0, negativeSegments: 6
4875: positiveSegments: 3, negativeSegments: 3
4879: positiveSegments: 4, negativeSegments: 3
4880: positiveSegments: 6, negativeSegments: 3
4882: positiveSegments: 0, negativeSegments: 6
4883: positiveSegments: 0, negativeSegments: 3
4886: exit early, no segments to save
4886: positiveSegments: 0, negativeSegments: 0
4887: positiveSegments: 16, negativeSegments: 18
4893: positiveSegments: 19, negativeSegments: 0
4894: positiveSegments: 8, negativeSegments: 6
4897: positiveSegments: 6, negativeSegments: 3
4899: positiveSegments: 0, negativeSegments: 12
4901: exit early, no segments to save
4901: positiveSegments: 0, negativeSegments: 0
4902: positiveSegments: 9, negativeSegments: 3
4903: positiveSegments: 0, negativeSegments: 3
4904: exit early, no segments to save
4904: positiveSegments: 0, negativeSegments: 0
4907: positiveSegments: 4, negativeSegments: 6
4911: positiveSegments: 14, negativeSegments: 9
4912: positiveSegments: 8, negativeSegments: 15
4913: positiveSegments: 0, negativeSegments: 3
4914: positiveSegments: 2, negativeSegments: 0
4916: positiveSegments: 17, negativeSegments: 0
4925: positiveSegments: 0, negativeSegments: 6
count processed: 2400, current case index: 4929
4929: positiveSegments: 6, negativeSegments: 3
4932: positiveSegments: 0, negativeSegments: 6
4933: positiveSegments: 17, negativeSegments: 0
4934: positiveSegments: 22, negativeSegments: 15
4935: positiveSegments: 0, negativeSegments: 6
4936: exit early, no segments to save
4936: positiveSegments: 0, negativeSegments: 0
4938: positiveSegments: 0, negativeSegments: 3
4939: positiveSegments: 4, negativeSegments: 6
4941: positiveSegments: 0, negativeSegments: 3
4942: positiveSegments: 14, negativeSegments: 3
4943: positiveSegments: 0, negativeSegments: 9
4946: positiveSegments: 4, negativeSegments: 0
4947: positiveSegments: 0, negativeSegments: 18
4949: positiveSegments: 0, negativeSegments: 6
4951: positiveSegments: 0, negativeSegments: 6
4953: positiveSegments: 12, negativeSegments: 6
4954: positiveSegments: 4, negativeSegments: 6
4957: positiveSegments: 4, negativeSegments: 9
4958: positiveSegments: 16, negativeSegments: 6
4959: positiveSegments: 21, negativeSegments: 3
4964: exit early, no segments to save
4964: positiveSegments: 0, negativeSegments: 0
4965: positiveSegments: 0, negativeSegments: 6
4966: positiveSegments: 16, negativeSegments: 6
4971: positiveSegments: 7, negativeSegments: 0
4973: positiveSegments: 4, negativeSegments: 6
4974: positiveSegments: 4, negativeSegments: 6
4976: positiveSegments: 4, negativeSegments: 9
4977: positiveSegments: 7, negativeSegments: 0
4982: positiveSegments: 4, negativeSegments: 3
4985: exit early, no segments to save
4985: positiveSegments: 0, negativeSegments: 0
4987: positiveSegments: 0, negativeSegments: 12
4989: positiveSegments: 4, negativeSegments: 6
4991: positiveSegments: 0, negativeSegments: 6
4992: positiveSegments: 6, negativeSegments: 0
4995: positiveSegments: 3, negativeSegments: 15
4997: positiveSegments: 31, negativeSegments: 3
4998: exit early, no segments to save
4998: positiveSegments: 0, negativeSegments: 0
4999: positiveSegments: 3, negativeSegments: 12
5001: exit early, no segments to save
5001: positiveSegments: 0, negativeSegments: 0
5004: positiveSegments: 6, negativeSegments: 0
5005: positiveSegments: 11, negativeSegments: 0
5006: positiveSegments: 20, negativeSegments: 3
5008: positiveSegments: 0, negativeSegments: 6
5010: positiveSegments: 10, negativeSegments: 15
5014: positiveSegments: 0, negativeSegments: 15
5015: positiveSegments: 0, negativeSegments: 9
5018: positiveSegments: 12, negativeSegments: 0
5019: positiveSegments: 12, negativeSegments: 12
5021: positiveSegments: 0, negativeSegments: 6
5024: positiveSegments: 4, negativeSegments: 3
5027: positiveSegments: 4, negativeSegments: 0
5029: positiveSegments: 0, negativeSegments: 3
5031: positiveSegments: 3, negativeSegments: 0
5033: positiveSegments: 0, negativeSegments: 3
5036: positiveSegments: 25, negativeSegments: 0
5040: positiveSegments: 7, negativeSegments: 3
5043: positiveSegments: 10, negativeSegments: 6
5044: positiveSegments: 12, negativeSegments: 6
5045: positiveSegments: 8, negativeSegments: 3
5046: positiveSegments: 3, negativeSegments: 0
5052: positiveSegments: 13, negativeSegments: 0
5059: positiveSegments: 21, negativeSegments: 0
5060: positiveSegments: 0, negativeSegments: 21
5061: positiveSegments: 1, negativeSegments: 0
5068: positiveSegments: 8, negativeSegments: 3
5070: positiveSegments: 4, negativeSegments: 0
5072: positiveSegments: 0, negativeSegments: 12
5077: positiveSegments: 3, negativeSegments: 6
5079: positiveSegments: 0, negativeSegments: 6
5080: positiveSegments: 4, negativeSegments: 0
5084: positiveSegments: 12, negativeSegments: 0
5089: positiveSegments: 0, negativeSegments: 12
5090: positiveSegments: 8, negativeSegments: 3
5091: positiveSegments: 0, negativeSegments: 9
5092: positiveSegments: 0, negativeSegments: 3
5093: positiveSegments: 0, negativeSegments: 6
5099: positiveSegments: 22, negativeSegments: 12
5100: positiveSegments: 26, negativeSegments: 0
5104: positiveSegments: 0, negativeSegments: 6
5106: positiveSegments: 4, negativeSegments: 15
5108: positiveSegments: 12, negativeSegments: 3
5109: positiveSegments: 12, negativeSegments: 3
5110: positiveSegments: 7, negativeSegments: 0
5111: positiveSegments: 4, negativeSegments: 9
5112: positiveSegments: 3, negativeSegments: 9
5116: exit early, no segments to save
5116: positiveSegments: 0, negativeSegments: 0
5117: exit early, no segments to save
5117: positiveSegments: 0, negativeSegments: 0
5118: positiveSegments: 10, negativeSegments: 0
5119: positiveSegments: 28, negativeSegments: 3
5122: positiveSegments: 0, negativeSegments: 6
5124: positiveSegments: 0, negativeSegments: 3
5125: positiveSegments: 4, negativeSegments: 0
5126: positiveSegments: 4, negativeSegments: 3
5130: exit early, no segments to save
5130: positiveSegments: 0, negativeSegments: 0
5131: positiveSegments: 14, negativeSegments: 3
5135: positiveSegments: 11, negativeSegments: 9
5137: positiveSegments: 0, negativeSegments: 9
5139: positiveSegments: 16, negativeSegments: 0
5140: positiveSegments: 0, negativeSegments: 9
5141: exit early, no segments to save
5141: positiveSegments: 0, negativeSegments: 0
count processed: 2500, current case index: 5142
5142: exit early, no segments to save
5142: positiveSegments: 0, negativeSegments: 0
5143: exit early, no segments to save
5143: positiveSegments: 0, negativeSegments: 0
5148: positiveSegments: 0, negativeSegments: 3
5149: positiveSegments: 4, negativeSegments: 0
5150: positiveSegments: 0, negativeSegments: 6
5151: exit early, no segments to save
5151: positiveSegments: 0, negativeSegments: 0
5152: positiveSegments: 14, negativeSegments: 6
5153: positiveSegments: 4, negativeSegments: 9
5155: positiveSegments: 4, negativeSegments: 3
5156: positiveSegments: 5, negativeSegments: 0
5157: positiveSegments: 2, negativeSegments: 0
5162: positiveSegments: 3, negativeSegments: 9
5163: positiveSegments: 11, negativeSegments: 9
5164: exit early, no segments to save
5164: positiveSegments: 0, negativeSegments: 0
5166: positiveSegments: 4, negativeSegments: 12
5173: positiveSegments: 26, negativeSegments: 0
5174: positiveSegments: 17, negativeSegments: 0
5175: exit early, no segments to save
5175: positiveSegments: 0, negativeSegments: 0
5178: positiveSegments: 5, negativeSegments: 6
5179: exit early, no segments to save
5179: positiveSegments: 0, negativeSegments: 0
5180: positiveSegments: 0, negativeSegments: 12
5182: positiveSegments: 0, negativeSegments: 9
5183: exit early, no segments to save
5183: positiveSegments: 0, negativeSegments: 0
5184: positiveSegments: 8, negativeSegments: 3
5185: positiveSegments: 6, negativeSegments: 0
5187: positiveSegments: 5, negativeSegments: 0
5192: positiveSegments: 0, negativeSegments: 3
5193: positiveSegments: 0, negativeSegments: 6
5194: exit early, no segments to save
5194: positiveSegments: 0, negativeSegments: 0
5195: positiveSegments: 4, negativeSegments: 3
5198: positiveSegments: 10, negativeSegments: 6
5201: positiveSegments: 28, negativeSegments: 0
5202: positiveSegments: 0, negativeSegments: 9
5203: positiveSegments: 12, negativeSegments: 12
5204: positiveSegments: 3, negativeSegments: 0
5209: exit early, no segments to save
5209: positiveSegments: 0, negativeSegments: 0
5213: positiveSegments: 4, negativeSegments: 6
5214: positiveSegments: 0, negativeSegments: 3
5217: positiveSegments: 6, negativeSegments: 0
5218: exit early, no segments to save
5218: positiveSegments: 0, negativeSegments: 0
5221: positiveSegments: 8, negativeSegments: 0
5222: positiveSegments: 9, negativeSegments: 9
5223: exit early, no segments to save
5223: positiveSegments: 0, negativeSegments: 0
5224: positiveSegments: 8, negativeSegments: 15
5225: positiveSegments: 8, negativeSegments: 0
5226: positiveSegments: 2, negativeSegments: 0
5229: positiveSegments: 8, negativeSegments: 6
5230: positiveSegments: 5, negativeSegments: 0
5232: positiveSegments: 0, negativeSegments: 12
5234: exit early, no segments to save
5234: positiveSegments: 0, negativeSegments: 0
5235: positiveSegments: 4, negativeSegments: 21
5237: positiveSegments: 8, negativeSegments: 0
5245: positiveSegments: 21, negativeSegments: 6
5246: positiveSegments: 4, negativeSegments: 3
5247: positiveSegments: 8, negativeSegments: 9
5251: exit early, no segments to save
5251: positiveSegments: 0, negativeSegments: 0
5253: exit early, no segments to save
5253: positiveSegments: 0, negativeSegments: 0
5254: exit early, no segments to save
5254: positiveSegments: 0, negativeSegments: 0
5255: positiveSegments: 0, negativeSegments: 9
5259: positiveSegments: 11, negativeSegments: 0
5264: positiveSegments: 0, negativeSegments: 18
5265: exit early, no segments to save
5265: positiveSegments: 0, negativeSegments: 0
5266: positiveSegments: 4, negativeSegments: 0
5267: positiveSegments: 2, negativeSegments: 6
5270: positiveSegments: 6, negativeSegments: 0
5271: positiveSegments: 0, negativeSegments: 15
5274: exit early, no segments to save
5274: positiveSegments: 0, negativeSegments: 0
5277: positiveSegments: 4, negativeSegments: 12
5278: positiveSegments: 0, negativeSegments: 9
5280: positiveSegments: 4, negativeSegments: 0
5283: positiveSegments: 0, negativeSegments: 3
5284: positiveSegments: 15, negativeSegments: 0
5285: positiveSegments: 8, negativeSegments: 0
5288: positiveSegments: 4, negativeSegments: 3
5292: positiveSegments: 2, negativeSegments: 0
5295: positiveSegments: 4, negativeSegments: 9
5296: positiveSegments: 4, negativeSegments: 6
5297: positiveSegments: 3, negativeSegments: 0
5298: positiveSegments: 28, negativeSegments: 6
5299: positiveSegments: 4, negativeSegments: 0
5301: exit early, no segments to save
5301: positiveSegments: 0, negativeSegments: 0
5302: positiveSegments: 8, negativeSegments: 0
5304: positiveSegments: 24, negativeSegments: 0
5305: positiveSegments: 18, negativeSegments: 6
5308: positiveSegments: 0, negativeSegments: 18
5309: positiveSegments: 0, negativeSegments: 6
5310: positiveSegments: 11, negativeSegments: 0
5311: positiveSegments: 16, negativeSegments: 3
5314: positiveSegments: 0, negativeSegments: 15
5317: positiveSegments: 4, negativeSegments: 12
5319: positiveSegments: 9, negativeSegments: 9
5321: positiveSegments: 0, negativeSegments: 12
5322: positiveSegments: 10, negativeSegments: 6
5323: positiveSegments: 4, negativeSegments: 3
5324: positiveSegments: 4, negativeSegments: 0
5327: exit early, no segments to save
5327: positiveSegments: 0, negativeSegments: 0
5332: positiveSegments: 0, negativeSegments: 3
5339: exit early, no segments to save
5339: positiveSegments: 0, negativeSegments: 0
5342: positiveSegments: 0, negativeSegments: 6
5344: positiveSegments: 0, negativeSegments: 6
count processed: 2600, current case index: 5346
5346: positiveSegments: 28, negativeSegments: 6
5347: positiveSegments: 11, negativeSegments: 12
5348: exit early, no segments to save
5348: positiveSegments: 0, negativeSegments: 0
5349: positiveSegments: 7, negativeSegments: 6
5352: positiveSegments: 0, negativeSegments: 12
5353: positiveSegments: 8, negativeSegments: 6
5356: exit early, no segments to save
5356: positiveSegments: 0, negativeSegments: 0
5359: positiveSegments: 0, negativeSegments: 3
5360: positiveSegments: 11, negativeSegments: 21
5362: positiveSegments: 20, negativeSegments: 3
5363: positiveSegments: 8, negativeSegments: 12
5364: positiveSegments: 0, negativeSegments: 6
5366: exit early, no segments to save
5366: positiveSegments: 0, negativeSegments: 0
5367: positiveSegments: 12, negativeSegments: 3
5368: positiveSegments: 4, negativeSegments: 0
5371: positiveSegments: 4, negativeSegments: 6
5372: positiveSegments: 8, negativeSegments: 3
5379: positiveSegments: 5, negativeSegments: 3
5383: positiveSegments: 0, negativeSegments: 6
5387: positiveSegments: 10, negativeSegments: 9
5388: positiveSegments: 0, negativeSegments: 9
5390: exit early, no segments to save
5390: positiveSegments: 0, negativeSegments: 0
5393: positiveSegments: 0, negativeSegments: 3
5394: positiveSegments: 4, negativeSegments: 0
5395: positiveSegments: 0, negativeSegments: 6
5396: positiveSegments: 14, negativeSegments: 18
5397: positiveSegments: 2, negativeSegments: 0
5399: positiveSegments: 2, negativeSegments: 3
5402: exit early, no segments to save
5402: positiveSegments: 0, negativeSegments: 0
5403: positiveSegments: 8, negativeSegments: 9
5406: positiveSegments: 0, negativeSegments: 3
5411: positiveSegments: 3, negativeSegments: 0
5415: positiveSegments: 13, negativeSegments: 0
5416: positiveSegments: 38, negativeSegments: 3
5420: positiveSegments: 11, negativeSegments: 3
5421: positiveSegments: 26, negativeSegments: 6
5422: exit early, no segments to save
5422: positiveSegments: 0, negativeSegments: 0
5423: positiveSegments: 22, negativeSegments: 0
5425: positiveSegments: 4, negativeSegments: 9
5427: positiveSegments: 8, negativeSegments: 3
5431: positiveSegments: 0, negativeSegments: 3
5434: positiveSegments: 3, negativeSegments: 6
5436: exit early, no segments to save
5436: positiveSegments: 0, negativeSegments: 0
5442: positiveSegments: 4, negativeSegments: 3
5443: positiveSegments: 10, negativeSegments: 6
5446: positiveSegments: 4, negativeSegments: 0
5449: positiveSegments: 4, negativeSegments: 0
5451: positiveSegments: 16, negativeSegments: 3
5453: positiveSegments: 5, negativeSegments: 0
5454: positiveSegments: 7, negativeSegments: 0
5456: positiveSegments: 0, negativeSegments: 6
5458: positiveSegments: 32, negativeSegments: 9
5460: positiveSegments: 2, negativeSegments: 0
5462: positiveSegments: 0, negativeSegments: 9
5463: positiveSegments: 0, negativeSegments: 6
5467: positiveSegments: 13, negativeSegments: 3
5474: positiveSegments: 4, negativeSegments: 3
5475: positiveSegments: 0, negativeSegments: 9
5476: exit early, no segments to save
5476: positiveSegments: 0, negativeSegments: 0
5478: positiveSegments: 4, negativeSegments: 0
5479: positiveSegments: 0, negativeSegments: 6
5480: positiveSegments: 0, negativeSegments: 9
5484: positiveSegments: 0, negativeSegments: 6
5486: positiveSegments: 8, negativeSegments: 3
5487: positiveSegments: 4, negativeSegments: 6
5490: positiveSegments: 7, negativeSegments: 0
5492: positiveSegments: 4, negativeSegments: 6
5495: positiveSegments: 4, negativeSegments: 9
5497: positiveSegments: 26, negativeSegments: 3
5499: positiveSegments: 0, negativeSegments: 3
5500: positiveSegments: 1, negativeSegments: 0
5501: exit early, no segments to save
5501: positiveSegments: 0, negativeSegments: 0
5502: positiveSegments: 5, negativeSegments: 0
5505: positiveSegments: 7, negativeSegments: 3
5507: positiveSegments: 0, negativeSegments: 12
5508: positiveSegments: 0, negativeSegments: 12
5509: positiveSegments: 0, negativeSegments: 6
5511: positiveSegments: 6, negativeSegments: 3
5513: positiveSegments: 4, negativeSegments: 9
5515: positiveSegments: 3, negativeSegments: 12
5516: positiveSegments: 18, negativeSegments: 6
5517: positiveSegments: 4, negativeSegments: 6
5519: positiveSegments: 3, negativeSegments: 9
5520: positiveSegments: 0, negativeSegments: 3
5524: positiveSegments: 6, negativeSegments: 3
5526: positiveSegments: 0, negativeSegments: 6
5531: positiveSegments: 8, negativeSegments: 9
5533: positiveSegments: 0, negativeSegments: 3
5534: positiveSegments: 23, negativeSegments: 15
5536: positiveSegments: 0, negativeSegments: 3
5537: positiveSegments: 4, negativeSegments: 6
5538: positiveSegments: 11, negativeSegments: 0
5541: positiveSegments: 0, negativeSegments: 3
5544: exit early, no segments to save
5544: positiveSegments: 0, negativeSegments: 0
5546: positiveSegments: 6, negativeSegments: 0
5548: positiveSegments: 4, negativeSegments: 3
5552: positiveSegments: 22, negativeSegments: 0
5556: exit early, no segments to save
5556: positiveSegments: 0, negativeSegments: 0
5561: positiveSegments: 0, negativeSegments: 6
5562: exit early, no segments to save
5562: positiveSegments: 0, negativeSegments: 0
count processed: 2700, current case index: 5564
5564: positiveSegments: 14, negativeSegments: 0
5566: positiveSegments: 0, negativeSegments: 9
5568: positiveSegments: 12, negativeSegments: 3
5571: positiveSegments: 0, negativeSegments: 3
5572: positiveSegments: 0, negativeSegments: 9
5573: positiveSegments: 5, negativeSegments: 0
5574: positiveSegments: 8, negativeSegments: 9
5578: positiveSegments: 0, negativeSegments: 3
5582: positiveSegments: 8, negativeSegments: 15
5583: positiveSegments: 8, negativeSegments: 3
5585: positiveSegments: 10, negativeSegments: 3
5587: nothing saved, all segments filtered
5587: positiveSegments: 2, negativeSegments: 0
5589: positiveSegments: 4, negativeSegments: 6
5593: positiveSegments: 11, negativeSegments: 3
5594: positiveSegments: 0, negativeSegments: 3
5595: positiveSegments: 24, negativeSegments: 3
5597: positiveSegments: 4, negativeSegments: 0
5598: positiveSegments: 6, negativeSegments: 0
5600: positiveSegments: 8, negativeSegments: 0
5601: positiveSegments: 6, negativeSegments: 6
5602: positiveSegments: 0, negativeSegments: 12
5603: positiveSegments: 4, negativeSegments: 6
5607: positiveSegments: 25, negativeSegments: 9
5608: exit early, no segments to save
5608: positiveSegments: 0, negativeSegments: 0
5610: positiveSegments: 4, negativeSegments: 0
5612: positiveSegments: 18, negativeSegments: 3
5613: positiveSegments: 8, negativeSegments: 9
5614: positiveSegments: 2, negativeSegments: 0
5616: positiveSegments: 0, negativeSegments: 9
5617: exit early, no segments to save
5617: positiveSegments: 0, negativeSegments: 0
5618: positiveSegments: 0, negativeSegments: 18
5620: positiveSegments: 10, negativeSegments: 3
5621: positiveSegments: 10, negativeSegments: 12
5624: positiveSegments: 12, negativeSegments: 3
5626: positiveSegments: 8, negativeSegments: 3
5627: positiveSegments: 0, negativeSegments: 15
5629: positiveSegments: 4, negativeSegments: 0
5630: positiveSegments: 4, negativeSegments: 12
5633: positiveSegments: 13, negativeSegments: 0
5635: positiveSegments: 4, negativeSegments: 0
5637: positiveSegments: 4, negativeSegments: 15
5638: positiveSegments: 15, negativeSegments: 3
5641: positiveSegments: 8, negativeSegments: 6
5642: positiveSegments: 4, negativeSegments: 0
5646: positiveSegments: 0, negativeSegments: 3
5647: positiveSegments: 0, negativeSegments: 3
5648: positiveSegments: 8, negativeSegments: 6
5650: positiveSegments: 5, negativeSegments: 3
5654: positiveSegments: 0, negativeSegments: 6
5655: positiveSegments: 8, negativeSegments: 3
5657: positiveSegments: 8, negativeSegments: 3
5658: positiveSegments: 12, negativeSegments: 3
5659: positiveSegments: 0, negativeSegments: 12
5662: positiveSegments: 0, negativeSegments: 3
5664: exit early, no segments to save
5664: positiveSegments: 0, negativeSegments: 0
5665: positiveSegments: 4, negativeSegments: 15
5669: positiveSegments: 8, negativeSegments: 12
5670: positiveSegments: 12, negativeSegments: 12
5671: positiveSegments: 0, negativeSegments: 6
5673: positiveSegments: 12, negativeSegments: 0
5675: positiveSegments: 4, negativeSegments: 9
5677: positiveSegments: 1, negativeSegments: 6
5678: positiveSegments: 4, negativeSegments: 30
5680: positiveSegments: 0, negativeSegments: 6
5682: positiveSegments: 15, negativeSegments: 0
5684: positiveSegments: 10, negativeSegments: 6
5685: positiveSegments: 5, negativeSegments: 6
5687: positiveSegments: 22, negativeSegments: 6
5690: positiveSegments: 4, negativeSegments: 9
5691: positiveSegments: 2, negativeSegments: 0
5692: positiveSegments: 0, negativeSegments: 6
5693: exit early, no segments to save
5693: positiveSegments: 0, negativeSegments: 0
5694: positiveSegments: 0, negativeSegments: 9
5696: positiveSegments: 7, negativeSegments: 0
5698: positiveSegments: 35, negativeSegments: 0
5703: positiveSegments: 4, negativeSegments: 6
5711: exit early, no segments to save
5711: positiveSegments: 0, negativeSegments: 0
5715: positiveSegments: 12, negativeSegments: 18
5717: exit early, no segments to save
5717: positiveSegments: 0, negativeSegments: 0
5718: positiveSegments: 0, negativeSegments: 3
5719: positiveSegments: 2, negativeSegments: 3
5721: positiveSegments: 0, negativeSegments: 3
5724: positiveSegments: 0, negativeSegments: 18
5725: positiveSegments: 6, negativeSegments: 9
5727: positiveSegments: 0, negativeSegments: 6
5729: positiveSegments: 0, negativeSegments: 15
5733: positiveSegments: 0, negativeSegments: 15
5734: exit early, no segments to save
5734: positiveSegments: 0, negativeSegments: 0
5743: positiveSegments: 0, negativeSegments: 3
5745: positiveSegments: 7, negativeSegments: 0
5746: positiveSegments: 24, negativeSegments: 3
5749: positiveSegments: 4, negativeSegments: 6
5750: positiveSegments: 8, negativeSegments: 0
5751: positiveSegments: 4, negativeSegments: 12
5753: positiveSegments: 5, negativeSegments: 0
5755: positiveSegments: 4, negativeSegments: 0
5759: positiveSegments: 4, negativeSegments: 6
5760: positiveSegments: 21, negativeSegments: 18
5765: positiveSegments: 6, negativeSegments: 0
5769: positiveSegments: 0, negativeSegments: 12
count processed: 2800, current case index: 5771
5771: positiveSegments: 25, negativeSegments: 3
5772: positiveSegments: 0, negativeSegments: 12
5777: positiveSegments: 0, negativeSegments: 9
5780: positiveSegments: 8, negativeSegments: 6
5781: positiveSegments: 3, negativeSegments: 3
5782: positiveSegments: 0, negativeSegments: 3
5783: positiveSegments: 8, negativeSegments: 15
5784: positiveSegments: 9, negativeSegments: 0
5787: positiveSegments: 53, negativeSegments: 0
5788: positiveSegments: 4, negativeSegments: 12
5793: positiveSegments: 0, negativeSegments: 12
5795: positiveSegments: 11, negativeSegments: 6
5799: positiveSegments: 4, negativeSegments: 0
5800: exit early, no segments to save
5800: positiveSegments: 0, negativeSegments: 0
5801: positiveSegments: 0, negativeSegments: 3
5805: positiveSegments: 2, negativeSegments: 0
5806: positiveSegments: 16, negativeSegments: 3
5808: positiveSegments: 0, negativeSegments: 3
5809: positiveSegments: 3, negativeSegments: 21
5810: exit early, no segments to save
5810: positiveSegments: 0, negativeSegments: 0
5811: positiveSegments: 2, negativeSegments: 0
5814: exit early, no segments to save
5814: positiveSegments: 0, negativeSegments: 0
5816: positiveSegments: 0, negativeSegments: 12
5817: exit early, no segments to save
5817: positiveSegments: 0, negativeSegments: 0
5819: positiveSegments: 12, negativeSegments: 15
5823: exit early, no segments to save
5823: positiveSegments: 0, negativeSegments: 0
5825: positiveSegments: 7, negativeSegments: 12
5826: positiveSegments: 13, negativeSegments: 15
5827: positiveSegments: 8, negativeSegments: 6
5829: positiveSegments: 6, negativeSegments: 6
5831: positiveSegments: 21, negativeSegments: 3
5832: positiveSegments: 0, negativeSegments: 6
5834: positiveSegments: 0, negativeSegments: 6
5837: positiveSegments: 7, negativeSegments: 6
5839: positiveSegments: 0, negativeSegments: 9
5840: positiveSegments: 0, negativeSegments: 24
5842: positiveSegments: 0, negativeSegments: 9
5843: positiveSegments: 4, negativeSegments: 12
5844: positiveSegments: 12, negativeSegments: 6
5848: positiveSegments: 4, negativeSegments: 0
5849: positiveSegments: 18, negativeSegments: 0
5851: positiveSegments: 0, negativeSegments: 9
5859: positiveSegments: 21, negativeSegments: 9
5860: positiveSegments: 12, negativeSegments: 9
5861: positiveSegments: 3, negativeSegments: 0
5862: positiveSegments: 33, negativeSegments: 0
5864: positiveSegments: 0, negativeSegments: 3
5865: positiveSegments: 15, negativeSegments: 3
5866: positiveSegments: 15, negativeSegments: 9
5869: positiveSegments: 12, negativeSegments: 9
5870: positiveSegments: 0, negativeSegments: 9
5871: positiveSegments: 0, negativeSegments: 3
5872: positiveSegments: 19, negativeSegments: 6
5873: positiveSegments: 7, negativeSegments: 3
5875: positiveSegments: 26, negativeSegments: 3
5882: exit early, no segments to save
5882: positiveSegments: 0, negativeSegments: 0
5884: positiveSegments: 5, negativeSegments: 0
5887: positiveSegments: 8, negativeSegments: 0
5888: positiveSegments: 0, negativeSegments: 3
5889: positiveSegments: 0, negativeSegments: 3
5890: positiveSegments: 7, negativeSegments: 3
5891: positiveSegments: 0, negativeSegments: 3
5892: positiveSegments: 0, negativeSegments: 3
5894: positiveSegments: 7, negativeSegments: 0
5895: positiveSegments: 4, negativeSegments: 9
5902: positiveSegments: 7, negativeSegments: 3
5904: positiveSegments: 8, negativeSegments: 6
5907: positiveSegments: 0, negativeSegments: 3
5908: exit early, no segments to save
5908: positiveSegments: 0, negativeSegments: 0
5911: positiveSegments: 6, negativeSegments: 3
5912: positiveSegments: 4, negativeSegments: 6
5914: positiveSegments: 2, negativeSegments: 3
5916: exit early, no segments to save
5916: positiveSegments: 0, negativeSegments: 0
5917: positiveSegments: 7, negativeSegments: 0
5918: positiveSegments: 0, negativeSegments: 9
5933: positiveSegments: 4, negativeSegments: 0
5934: positiveSegments: 0, negativeSegments: 3
5937: positiveSegments: 7, negativeSegments: 0
5938: positiveSegments: 4, negativeSegments: 6
5940: positiveSegments: 4, negativeSegments: 0
5942: positiveSegments: 6, negativeSegments: 3
5943: positiveSegments: 0, negativeSegments: 3
5944: positiveSegments: 4, negativeSegments: 9
5945: positiveSegments: 2, negativeSegments: 0
5946: positiveSegments: 12, negativeSegments: 6
5948: positiveSegments: 7, negativeSegments: 0
5950: positiveSegments: 11, negativeSegments: 9
5951: positiveSegments: 0, negativeSegments: 3
5954: positiveSegments: 8, negativeSegments: 0
5956: positiveSegments: 4, negativeSegments: 6
5958: positiveSegments: 0, negativeSegments: 12
5959: exit early, no segments to save
5959: positiveSegments: 0, negativeSegments: 0
5961: positiveSegments: 0, negativeSegments: 3
5964: positiveSegments: 0, negativeSegments: 15
5965: positiveSegments: 8, negativeSegments: 0
5966: positiveSegments: 4, negativeSegments: 6
5967: positiveSegments: 21, negativeSegments: 9
5970: positiveSegments: 0, negativeSegments: 3
5971: exit early, no segments to save
5971: positiveSegments: 0, negativeSegments: 0
5973: positiveSegments: 0, negativeSegments: 9
count processed: 2900, current case index: 5974
5974: exit early, no segments to save
5974: positiveSegments: 0, negativeSegments: 0
5975: positiveSegments: 9, negativeSegments: 3
5976: positiveSegments: 14, negativeSegments: 0
5977: positiveSegments: 8, negativeSegments: 9
5981: positiveSegments: 15, negativeSegments: 0
5982: positiveSegments: 4, negativeSegments: 0
5983: positiveSegments: 17, negativeSegments: 0
5986: positiveSegments: 4, negativeSegments: 9
5987: positiveSegments: 5, negativeSegments: 3
5989: positiveSegments: 5, negativeSegments: 3
5993: positiveSegments: 22, negativeSegments: 9
5994: positiveSegments: 4, negativeSegments: 0
5997: positiveSegments: 5, negativeSegments: 6
6000: positiveSegments: 0, negativeSegments: 21
6003: positiveSegments: 8, negativeSegments: 3
6006: exit early, no segments to save
6006: positiveSegments: 0, negativeSegments: 0
6007: positiveSegments: 14, negativeSegments: 3
6009: positiveSegments: 22, negativeSegments: 6
6010: positiveSegments: 4, negativeSegments: 12
6013: positiveSegments: 1, negativeSegments: 0
6015: positiveSegments: 4, negativeSegments: 0
6016: positiveSegments: 0, negativeSegments: 3
6017: positiveSegments: 0, negativeSegments: 9
6020: positiveSegments: 0, negativeSegments: 18
6022: positiveSegments: 8, negativeSegments: 0
6027: exit early, no segments to save
6027: positiveSegments: 0, negativeSegments: 0
6028: positiveSegments: 6, negativeSegments: 0
6029: positiveSegments: 0, negativeSegments: 6
6031: positiveSegments: 8, negativeSegments: 3
6032: exit early, no segments to save
6032: positiveSegments: 0, negativeSegments: 0
6037: positiveSegments: 4, negativeSegments: 6
6039: positiveSegments: 13, negativeSegments: 12
6041: exit early, no segments to save
6041: positiveSegments: 0, negativeSegments: 0
6042: exit early, no segments to save
6042: positiveSegments: 0, negativeSegments: 0
6043: positiveSegments: 14, negativeSegments: 6
6047: positiveSegments: 0, negativeSegments: 9
6053: positiveSegments: 0, negativeSegments: 3
6055: exit early, no segments to save
6055: positiveSegments: 0, negativeSegments: 0
6056: exit early, no segments to save
6056: positiveSegments: 0, negativeSegments: 0
6057: exit early, no segments to save
6057: positiveSegments: 0, negativeSegments: 0
6058: positiveSegments: 28, negativeSegments: 9
6059: positiveSegments: 0, negativeSegments: 9
6060: positiveSegments: 0, negativeSegments: 6
6061: positiveSegments: 4, negativeSegments: 12
6063: positiveSegments: 10, negativeSegments: 9
6065: positiveSegments: 0, negativeSegments: 3
6066: positiveSegments: 18, negativeSegments: 0
6067: exit early, no segments to save
6067: positiveSegments: 0, negativeSegments: 0
6069: positiveSegments: 22, negativeSegments: 12
6070: positiveSegments: 0, negativeSegments: 6
6071: positiveSegments: 22, negativeSegments: 0
6074: positiveSegments: 4, negativeSegments: 18
6076: positiveSegments: 11, negativeSegments: 6
6077: positiveSegments: 13, negativeSegments: 6
6080: positiveSegments: 2, negativeSegments: 0
6082: positiveSegments: 25, negativeSegments: 3
6083: positiveSegments: 9, negativeSegments: 9
6084: positiveSegments: 25, negativeSegments: 9
6085: positiveSegments: 6, negativeSegments: 3
6086: positiveSegments: 16, negativeSegments: 6
6087: positiveSegments: 2, negativeSegments: 3
6088: exit early, no segments to save
6088: positiveSegments: 0, negativeSegments: 0
6089: positiveSegments: 0, negativeSegments: 6
6097: exit early, no segments to save
6097: positiveSegments: 0, negativeSegments: 0
6098: positiveSegments: 0, negativeSegments: 3
6101: positiveSegments: 4, negativeSegments: 6
6102: positiveSegments: 7, negativeSegments: 3
6103: positiveSegments: 0, negativeSegments: 12
6104: positiveSegments: 0, negativeSegments: 6
6109: exit early, no segments to save
6109: positiveSegments: 0, negativeSegments: 0
6114: positiveSegments: 23, negativeSegments: 0
6119: positiveSegments: 4, negativeSegments: 12
6121: positiveSegments: 16, negativeSegments: 3
6124: positiveSegments: 8, negativeSegments: 0
6126: positiveSegments: 0, negativeSegments: 15
6127: positiveSegments: 6, negativeSegments: 0
6129: positiveSegments: 8, negativeSegments: 12
6131: exit early, no segments to save
6131: positiveSegments: 0, negativeSegments: 0
6132: positiveSegments: 4, negativeSegments: 0
6133: positiveSegments: 0, negativeSegments: 9
6134: positiveSegments: 0, negativeSegments: 9
6135: positiveSegments: 0, negativeSegments: 3
6136: positiveSegments: 6, negativeSegments: 6
6140: positiveSegments: 0, negativeSegments: 3
6141: positiveSegments: 10, negativeSegments: 0
6143: positiveSegments: 4, negativeSegments: 9
6144: positiveSegments: 5, negativeSegments: 0
6147: positiveSegments: 0, negativeSegments: 15
6152: positiveSegments: 15, negativeSegments: 0
6153: positiveSegments: 4, negativeSegments: 6
6154: positiveSegments: 3, negativeSegments: 0
6156: positiveSegments: 0, negativeSegments: 6
6159: positiveSegments: 36, negativeSegments: 3
6160: positiveSegments: 24, negativeSegments: 0
6163: positiveSegments: 13, negativeSegments: 3
6166: positiveSegments: 24, negativeSegments: 3
6167: positiveSegments: 0, negativeSegments: 15
6168: positiveSegments: 0, negativeSegments: 3
6169: positiveSegments: 0, negativeSegments: 12
6171: positiveSegments: 12, negativeSegments: 9
count processed: 3000, current case index: 6174
6174: positiveSegments: 0, negativeSegments: 6
6176: positiveSegments: 11, negativeSegments: 9
6178: positiveSegments: 17, negativeSegments: 3
6179: positiveSegments: 30, negativeSegments: 9
6180: exit early, no segments to save
6180: positiveSegments: 0, negativeSegments: 0
6182: positiveSegments: 8, negativeSegments: 9
6184: positiveSegments: 0, negativeSegments: 9
6185: positiveSegments: 4, negativeSegments: 6
6186: positiveSegments: 0, negativeSegments: 9
6190: positiveSegments: 3, negativeSegments: 9
6191: positiveSegments: 8, negativeSegments: 3
6192: exit early, no segments to save
6192: positiveSegments: 0, negativeSegments: 0
6194: positiveSegments: 0, negativeSegments: 6
6195: positiveSegments: 8, negativeSegments: 3
6196: positiveSegments: 0, negativeSegments: 9
6198: positiveSegments: 0, negativeSegments: 6
6199: positiveSegments: 4, negativeSegments: 6
6200: positiveSegments: 0, negativeSegments: 3
6204: exit early, no segments to save
6204: positiveSegments: 0, negativeSegments: 0
6205: exit early, no segments to save
6205: positiveSegments: 0, negativeSegments: 0
6206: positiveSegments: 4, negativeSegments: 0
6208: positiveSegments: 0, negativeSegments: 3
6210: positiveSegments: 0, negativeSegments: 3
6214: positiveSegments: 5, negativeSegments: 6
6217: positiveSegments: 29, negativeSegments: 3
6218: positiveSegments: 4, negativeSegments: 6
6219: positiveSegments: 4, negativeSegments: 9
6220: positiveSegments: 25, negativeSegments: 12
6224: positiveSegments: 0, negativeSegments: 6
6227: positiveSegments: 10, negativeSegments: 0
6228: positiveSegments: 4, negativeSegments: 0
6230: positiveSegments: 4, negativeSegments: 3
6233: positiveSegments: 1, negativeSegments: 0
6235: positiveSegments: 0, negativeSegments: 3
6238: positiveSegments: 3, negativeSegments: 3
6239: positiveSegments: 8, negativeSegments: 3
6240: positiveSegments: 4, negativeSegments: 0
6241: positiveSegments: 4, negativeSegments: 9
6248: positiveSegments: 12, negativeSegments: 3
6250: positiveSegments: 0, negativeSegments: 6
6254: positiveSegments: 4, negativeSegments: 6
6255: positiveSegments: 4, negativeSegments: 12
6257: positiveSegments: 0, negativeSegments: 21
6260: positiveSegments: 10, negativeSegments: 0
6261: exit early, no segments to save
6261: positiveSegments: 0, negativeSegments: 0
6262: positiveSegments: 4, negativeSegments: 3
6264: positiveSegments: 0, negativeSegments: 18
6266: positiveSegments: 11, negativeSegments: 3
6267: positiveSegments: 4, negativeSegments: 6
6268: positiveSegments: 0, negativeSegments: 3
6269: positiveSegments: 6, negativeSegments: 0
6270: positiveSegments: 0, negativeSegments: 15
6271: exit early, no segments to save
6271: positiveSegments: 0, negativeSegments: 0
6273: positiveSegments: 0, negativeSegments: 6
6275: positiveSegments: 4, negativeSegments: 0
6277: exit early, no segments to save
6277: positiveSegments: 0, negativeSegments: 0
6279: positiveSegments: 0, negativeSegments: 12
6280: positiveSegments: 0, negativeSegments: 9
6281: positiveSegments: 23, negativeSegments: 0
6282: positiveSegments: 8, negativeSegments: 6
6284: positiveSegments: 5, negativeSegments: 3
6286: positiveSegments: 0, negativeSegments: 6
6289: positiveSegments: 4, negativeSegments: 0
6290: positiveSegments: 14, negativeSegments: 0
6292: positiveSegments: 10, negativeSegments: 6
6293: exit early, no segments to save
6293: positiveSegments: 0, negativeSegments: 0
6295: positiveSegments: 4, negativeSegments: 6
6296: positiveSegments: 13, negativeSegments: 6
6297: positiveSegments: 26, negativeSegments: 0
6298: positiveSegments: 0, negativeSegments: 6
6302: positiveSegments: 2, negativeSegments: 0
6305: positiveSegments: 0, negativeSegments: 9
6306: positiveSegments: 0, negativeSegments: 6
6307: positiveSegments: 0, negativeSegments: 3
6309: positiveSegments: 48, negativeSegments: 3
6311: positiveSegments: 11, negativeSegments: 3
6312: positiveSegments: 10, negativeSegments: 0
6314: positiveSegments: 4, negativeSegments: 3
6315: exit early, no segments to save
6315: positiveSegments: 0, negativeSegments: 0
6316: positiveSegments: 15, negativeSegments: 3
6317: positiveSegments: 18, negativeSegments: 0
6324: exit early, no segments to save
6324: positiveSegments: 0, negativeSegments: 0
6330: positiveSegments: 0, negativeSegments: 3
6331: positiveSegments: 2, negativeSegments: 0
6332: positiveSegments: 4, negativeSegments: 15
6339: positiveSegments: 0, negativeSegments: 3
6343: positiveSegments: 4, negativeSegments: 15
6345: positiveSegments: 0, negativeSegments: 9
6346: positiveSegments: 0, negativeSegments: 9
6351: positiveSegments: 19, negativeSegments: 9
6355: positiveSegments: 2, negativeSegments: 6
6357: positiveSegments: 7, negativeSegments: 12
6359: positiveSegments: 2, negativeSegments: 0
6360: positiveSegments: 8, negativeSegments: 0
6361: positiveSegments: 12, negativeSegments: 3
6362: positiveSegments: 12, negativeSegments: 3
6363: positiveSegments: 8, negativeSegments: 15
6366: positiveSegments: 0, negativeSegments: 6
6368: exit early, no segments to save
6368: positiveSegments: 0, negativeSegments: 0
6370: positiveSegments: 0, negativeSegments: 6
count processed: 3100, current case index: 6372
6372: positiveSegments: 0, negativeSegments: 9
6373: exit early, no segments to save
6373: positiveSegments: 0, negativeSegments: 0
6375: positiveSegments: 8, negativeSegments: 0
6376: positiveSegments: 10, negativeSegments: 0
6378: positiveSegments: 8, negativeSegments: 0
6381: positiveSegments: 0, negativeSegments: 3
6383: positiveSegments: 0, negativeSegments: 12
6385: positiveSegments: 24, negativeSegments: 0
6386: positiveSegments: 8, negativeSegments: 15
6388: nothing saved, all segments filtered
6388: positiveSegments: 2, negativeSegments: 0
extracted: 3110

Track and Segment Validity Checks¶

In [40]:
def printAbp(case_id_to_check, plot_invalid_only=False):
        vf_path = f'{VITAL_MINI}/{case_id_to_check:04d}_mini.vital'
        
        if not os.path.isfile(vf_path):
              return
        
        vf = vitaldb.VitalFile(vf_path)
        abp = vf.to_numpy(TRACK_NAMES[0], 1/500)
        
        print(f'Case {case_id_to_check}')
        print(f'ABP Shape: {abp.shape}')

        print(f'nanmin: {np.nanmin(abp)}')
        print(f'nanmean: {np.nanmean(abp)}')
        print(f'nanmax: {np.nanmax(abp)}')
        
        is_valid = isAbpSegmentValidNumpy(abp, debug=True)
        print(f'valid: {is_valid}')

        if plot_invalid_only and is_valid:
            return
            
        plt.figure(figsize=(20, 5))
        plt_color = 'C0' if is_valid else 'red'
        plt.plot(abp, plt_color)
        plt.title(f'ABP - Entire Track - Case {case_id_to_check} - {abp.shape[0] / 500} seconds')
        plt.axhline(y = 65, color = 'maroon', linestyle = '--')
        plt.show()
In [41]:
def printSegments(segmentsMap, case_id_to_check, print_label, normalize=False):
    for (x1, x2, r, abp, ecg, eeg) in segmentsMap[case_id_to_check]:
        print(f'{print_label}: Case {case_id_to_check}')
        print(f'lookback window: {r} min')
        print(f'start time: {x1}')
        print(f'end time: {x2}')
        print(f'length: {x2 - x1} sec')
        
        print(f'ABP Shape: {abp.shape}')
        print(f'ECG Shape: {ecg.shape}')
        print(f'EEG Shape: {eeg.shape}')

        print(f'nanmin: {np.nanmin(abp)}')
        print(f'nanmean: {np.nanmean(abp)}')
        print(f'nanmax: {np.nanmax(abp)}')
        
        is_valid = isAbpSegmentValidNumpy(abp, debug=True)
        print(f'valid: {is_valid}')

        # ABP normalization
        x_abp = np.copy(abp)
        if normalize:
            x_abp -= 65
            x_abp /= 65

        plt.figure(figsize=(20, 5))
        plt_color = 'C0' if is_valid else 'red'
        plt.plot(x_abp, plt_color)
        plt.title('ABP')
        plt.axhline(y = 65, color = 'maroon', linestyle = '--')
        plt.show()

        plt.figure(figsize=(20, 5))
        plt.plot(ecg, 'teal')
        plt.title('ECG')
        plt.show()

        plt.figure(figsize=(20, 5))
        plt.plot(eeg, 'indigo')
        plt.title('EEG')
        plt.show()

        print()
In [42]:
def printEvents(abp_raw, eventsMap, case_id_to_check, print_label, normalize=False):
    for (x1, x2) in eventsMap[case_id_to_check]:
        print(f'{print_label}: Case {case_id_to_check}')
        print(f'start time: {x1}')
        print(f'end time: {x2}')
        print(f'length: {x2 - x1} sec')

        abp = abp_raw[x1*500:x2*500]
        print(f'ABP Shape: {abp.shape}')

        print(f'nanmin: {np.nanmin(abp)}')
        print(f'nanmean: {np.nanmean(abp)}')
        print(f'nanmax: {np.nanmax(abp)}')
        
        is_valid = isAbpSegmentValidNumpy(abp, debug=True)
        print(f'valid: {is_valid}')

        # ABP normalization
        x_abp = np.copy(abp)
        if normalize:
            x_abp -= 65
            x_abp /= 65

        plt.figure(figsize=(20, 5))
        plt_color = 'C0' if is_valid else 'red'
        plt.plot(x_abp, plt_color)
        plt.title('ABP')
        plt.axhline(y = 65, color = 'maroon', linestyle = '--')
        plt.show()

        print()
In [43]:
def moving_average(x, seconds=60):
    w = seconds * 500
    return np.convolve(np.squeeze(x), np.ones(w), 'valid') / w
In [44]:
def printAbpOverlay(
    case_id_to_check,
    positiveSegmentsMap,
    negativeSegmentsMap,
    iohEventsMap,
    cleanEventsMap,
    movingAverage=False
):
    def overlay_segments(plt, segmentsMap, color, linestyle, positive=False):
        for (x1, x2, r, abp, ecg, eeg) in segmentsMap:
            sx1 = x1*500
            sx2 = x2*500
            mycolor = color
            if positive:
                if r == 3:
                    mycolor = 'red'
                elif r == 5:
                    mycolor = 'crimson'
                elif r == 10:
                    mycolor = 'tomato'
                else:
                    mycolor = 'salmon'
            plt.axvline(x = sx1, color = mycolor, linestyle = linestyle)
            plt.axvline(x = sx2, color = mycolor, linestyle = linestyle)
            plt.axvspan(sx1, sx2, facecolor = mycolor, alpha = 0.1)

    def overlay_events(plt, eventsMap, color, linestyle):
        for (x1, x2) in eventsMap:
            sx1 = x1*500
            sx2 = x2*500
            plt.axvline(x = sx1, color = color, linestyle = linestyle)
            plt.axvline(x = sx2, color = color, linestyle = linestyle)
            plt.axvspan(sx1, sx2, facecolor = color, alpha = 0.1)
    
    vf_path = f'{VITAL_MINI}/{case_id_to_check:04d}_mini.vital'

    if not os.path.isfile(vf_path):
          return

    vf = vitaldb.VitalFile(vf_path)
    abp = vf.to_numpy(TRACK_NAMES[0], 1/500)
    
    abp_mov_avg = None
    if movingAverage:
        abp_mov_avg = moving_average(abp)

    print(f'Case {case_id_to_check}')
    print(f'ABP Shape: {abp.shape}')

    print(f'nanmin: {np.nanmin(abp)}')
    print(f'nanmean: {np.nanmean(abp)}')
    print(f'nanmax: {np.nanmax(abp)}')

    is_valid = isAbpSegmentValidNumpy(abp, debug=True)
    print(f'valid: {is_valid}')

    plt.figure(figsize=(24, 8))
    plt_color = 'C0' if is_valid else 'red'
    plt.plot(abp, plt_color)
    plt.title(f'ABP - Entire Track - Case {case_id_to_check} - {abp.shape[0] / 500} seconds')
    plt.axhline(y = 65, color = 'maroon', linestyle = '--')
    
    if movingAverage:
        plt.plot(abp_mov_avg, 'maroon')

    # https://matplotlib.org/stable/gallery/lines_bars_and_markers/linestyles.html#linestyles
    
    overlay_segments(plt, positiveSegmentsMap[case_id_to_check], 'crimson', (0, (1, 1)), positive=True)
    
    overlay_segments(plt, negativeSegmentsMap[case_id_to_check], 'teal', (0, (1, 1)))

    overlay_events(plt, iohEventsMap[case_id_to_check], 'brown', '-')
    
    overlay_events(plt, cleanEventsMap[case_id_to_check], 'teal', '-')

    plt.show()

Reality Check All Cases¶

In [45]:
# Check if all ABPs are well formed.
DISPLAY_REALITY_CHECK_ABP=True
DISPLAY_REALITY_CHECK_ABP_FIRST_ONLY=True

if DISPLAY_REALITY_CHECK_ABP:
    for case_id_to_check in cases_of_interest_idx:
        printAbp(case_id_to_check, plot_invalid_only=False)
        
        if DISPLAY_REALITY_CHECK_ABP_FIRST_ONLY:
            break
Case 1
ABP Shape: (5771049, 1)
nanmin: -495.6260070800781
nanmean: 78.15254211425781
nanmax: 374.3236389160156
Presence of BP > 200
valid: False

Validate Malformed Vital Files - Missing One Or More Tracks¶

In [46]:
# These are Vital Files removed because of malformed ABP waveforms.
DISPLAY_MALFORMED_ABP=True
DISPLAY_MALFORMED_ABP_FIRST_ONLY=True

if DISPLAY_MALFORMED_ABP:
    malformed_case_ids = pd.read_csv('malformed_tracks_filter.csv', header=None, names=['caseid']).set_index('caseid').index

    for case_id_to_check in malformed_case_ids:
        printAbp(case_id_to_check)
        
        if DISPLAY_MALFORMED_ABP_FIRST_ONLY:
            break

Validate Cases With No Segments Saved¶

In [47]:
DISPLAY_NO_SEGMENTS_CASES=True
DISPLAY_NO_SEGMENTS_CASES_FIRST_ONLY=True

if DISPLAY_NO_SEGMENTS_CASES:
    no_segments_case_ids = [3413, 3476, 3533, 3992, 4328, 4648, 4703, 4733, 5130, 5501, 5693, 5908]

    for case_id_to_check in no_segments_case_ids:
        printAbp(case_id_to_check)
        
        if DISPLAY_NO_SEGMENTS_CASES_FIRST_ONLY:
            break
Case 3413
ABP Shape: (3430848, 1)
nanmin: -228.025146484375
nanmean: 48.44272232055664
nanmax: 293.3521423339844
>10% NaN
valid: False

Select Case For Segment Extraction Validation¶

Generate segment data for one or more cases. Perform a deep analysis of event and segment quality.

In [48]:
#mycoi = cases_of_interest_idx
my_cases_of_interest_idx = cases_of_interest_idx[:10]
#mycoi = [1]

# Note: By default, match extract segments processing block above.
# However, regenerate data real time to allow seeing impacts on segment extraction.
# This is why both checkCache and forceWrite are false by default.
positiveSegmentsMap, negativeSegmentsMap, iohEventsMap, cleanEventsMap = \
    extract_segments(my_cases_of_interest_idx, debug=False,
                     checkCache=False, forceWrite=False, returnSegments=True,
                     skipInvalidCleanEvents=SKIP_INVALID_CLEAN_EVENTS,
                     skipInvalidIohEvents=SKIP_INVALID_IOH_EVENTS)
1: positiveSegments: 8, negativeSegments: 3
4: positiveSegments: 22, negativeSegments: 3
7: positiveSegments: 8, negativeSegments: 6
10: positiveSegments: 20, negativeSegments: 6
12: positiveSegments: 22, negativeSegments: 0
13: positiveSegments: 8, negativeSegments: 0
16: positiveSegments: 8, negativeSegments: 6
19: positiveSegments: 33, negativeSegments: 3
20: positiveSegments: 8, negativeSegments: 6
22: positiveSegments: 8, negativeSegments: 12

Select a specific case to perform detailed low level analysis.

In [49]:
case_id_to_check = my_cases_of_interest_idx[0]
case_id_to_check
Out[49]:
1
In [50]:
print((
    len(positiveSegmentsMap[case_id_to_check]),
    len(negativeSegmentsMap[case_id_to_check]),
    len(iohEventsMap[case_id_to_check]),
    len(cleanEventsMap[case_id_to_check])
))
(8, 3, 7, 3)
In [51]:
printAbp(case_id_to_check)
Case 1
ABP Shape: (5771049, 1)
nanmin: -495.6260070800781
nanmean: 78.15254211425781
nanmax: 374.3236389160156
Presence of BP > 200
valid: False

Positive Events for Case - IOH Events¶

Used to define the range in front of which positive segments will be extracted. Positive samples happen in front of this region.

In [52]:
tmp_vf_path = f'{VITAL_MINI}/{case_id_to_check:04d}_mini.vital'
tmp_vf = vitaldb.VitalFile(tmp_vf_path)
tmp_abp = tmp_vf.to_numpy(TRACK_NAMES[0], 1/500)
In [53]:
printEvents(tmp_abp, iohEventsMap, case_id_to_check, 'IOH Event Segment', normalize=False)
IOH Event Segment: Case 1
start time: 1789
end time: 1850
length: 61 sec
ABP Shape: (30500, 1)
nanmin: 32.663482666015625
nanmean: 64.94046020507812
nanmax: 123.50955200195312
valid: True
IOH Event Segment: Case 1
start time: 1851
end time: 2114
length: 263 sec
ABP Shape: (131500, 1)
nanmin: 37.600799560546875
nanmean: 63.13670349121094
nanmax: 101.78549194335938
valid: True
IOH Event Segment: Case 1
start time: 2315
end time: 2376
length: 61 sec
ABP Shape: (30500, 1)
nanmin: -262.5861511230469
nanmean: 64.96014404296875
nanmax: 343.7124938964844
Presence of BP > 200
valid: False
IOH Event Segment: Case 1
start time: 4114
end time: 4200
length: 86 sec
ABP Shape: (43000, 1)
nanmin: 22.788909912109375
nanmean: 65.10448455810547
nanmax: 157.08309936523438
Presence of BP < 30
valid: False
IOH Event Segment: Case 1
start time: 4262
end time: 5351
length: 1089 sec
ABP Shape: (544500, 1)
nanmin: 36.613311767578125
nanmean: 60.45355987548828
nanmax: 112.64755249023438
valid: True
IOH Event Segment: Case 1
start time: 9097
end time: 9157
length: 60 sec
ABP Shape: (30000, 1)
nanmin: 40.563140869140625
nanmean: 64.99588012695312
nanmax: 108.69772338867188
valid: True
IOH Event Segment: Case 1
start time: 9158
end time: 9504
length: 346 sec
ABP Shape: (173000, 1)
nanmin: 39.575714111328125
nanmean: 62.33222961425781
nanmax: 104.74789428710938
valid: True

Negative Events for Case - Non-IOH Events¶

Used to define the range from in which negative segments will be extracted. Negative samples happen within this region.

In [54]:
printEvents(tmp_abp, cleanEventsMap, case_id_to_check, 'Clean Event Segment', normalize=False)
Clean Event Segment: Case 1
start time: 5352
end time: 7152
length: 1800 sec
ABP Shape: (900000, 1)
nanmin: 40.563140869140625
nanmean: 84.04817962646484
nanmax: 151.15835571289062
valid: True
Clean Event Segment: Case 1
start time: 7153
end time: 8953
length: 1800 sec
ABP Shape: (900000, 1)
nanmin: -495.6260070800781
nanmean: 99.71107482910156
nanmax: 368.3988952636719
Presence of BP > 200
valid: False
Clean Event Segment: Case 1
start time: 9505
end time: 11305
length: 1800 sec
ABP Shape: (900000, 1)
nanmin: -49.295440673828125
nanmean: 83.31828308105469
nanmax: 346.6748352050781
Presence of BP > 200
valid: False

Positive Segments for Case - IOH Events Predicted Using These¶

One minute regions sampled and used for training the model for "positive" events.

In [55]:
printSegments(positiveSegmentsMap, case_id_to_check, 'Positive Segment - IOH Event', normalize=False)
Positive Segment - IOH Event: Case 1
lookback window: 3 min
start time: 3874
end time: 3934
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 46.487884521484375
nanmean: 75.35091400146484
nanmax: 124.49703979492188
valid: True
Positive Segment - IOH Event: Case 1
lookback window: 5 min
start time: 3754
end time: 3814
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 45.500457763671875
nanmean: 74.010009765625
nanmax: 122.52212524414062
valid: True
Positive Segment - IOH Event: Case 1
lookback window: 10 min
start time: 3454
end time: 3514
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 52.412628173828125
nanmean: 86.52202606201172
nanmax: 148.19595336914062
valid: True
Positive Segment - IOH Event: Case 1
lookback window: 15 min
start time: 3154
end time: 3214
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 58.337371826171875
nanmean: 100.94869995117188
nanmax: 165.97018432617188
valid: True
Positive Segment - IOH Event: Case 1
lookback window: 3 min
start time: 8857
end time: 8917
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 64.26211547851562
nanmean: 97.10965728759766
nanmax: 157.08309936523438
valid: True
Positive Segment - IOH Event: Case 1
lookback window: 5 min
start time: 8737
end time: 8797
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 69.19943237304688
nanmean: 105.49205780029297
nanmax: 163.00784301757812
valid: True
Positive Segment - IOH Event: Case 1
lookback window: 10 min
start time: 8437
end time: 8497
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: -88.793701171875
nanmean: 130.44439697265625
nanmax: 305.2016296386719
Presence of BP > 200
valid: False
Positive Segment - IOH Event: Case 1
lookback window: 15 min
start time: 8137
end time: 8197
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 62.287200927734375
nanmean: 92.04788208007812
nanmax: 138.32138061523438
valid: True

Negative Segments for Case - Non-IOH Events Predicted Using These¶

One minute regions sampled and used for training the model for "negative" events.

In [56]:
printSegments(negativeSegmentsMap, case_id_to_check, 'Negative Segment - Non-Event', normalize=False)
Negative Segment - Non-Event: Case 1
lookback window: 0 min
start time: 5952
end time: 6012
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 52.412628173828125
nanmean: 76.36067962646484
nanmax: 120.54721069335938
valid: True
Negative Segment - Non-Event: Case 1
lookback window: 0 min
start time: 6252
end time: 6312
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 54.387542724609375
nanmean: 77.72315216064453
nanmax: 120.54721069335938
valid: True
Negative Segment - Non-Event: Case 1
lookback window: 0 min
start time: 6552
end time: 6612
length: 60 sec
ABP Shape: (30000,)
ECG Shape: (30000,)
EEG Shape: (7680,)
nanmin: 58.337371826171875
nanmean: 85.06087493896484
nanmax: 133.38412475585938
valid: True

Overlay Plot of All Events and Segments Extracted¶

For each of the cases in my_cases_of_interest_idx overlay the results of event and segment extraction.

In [57]:
DISPLAY_OVERLAY_CHECK_ABP=True
DISPLAY_OVERLAY_CHECK_ABP_FIRST_ONLY=False

if DISPLAY_OVERLAY_CHECK_ABP:
    for case_id_to_check in my_cases_of_interest_idx:
        printAbpOverlay(case_id_to_check, positiveSegmentsMap, 
                        negativeSegmentsMap, iohEventsMap, cleanEventsMap, movingAverage=True)
        
        if DISPLAY_OVERLAY_CHECK_ABP_FIRST_ONLY:
            break
Case 1
ABP Shape: (5771049, 1)
nanmin: -495.6260070800781
nanmean: 78.15254211425781
nanmax: 374.3236389160156
Presence of BP > 200
valid: False
Case 4
ABP Shape: (10494885, 1)
nanmin: -495.6260070800781
nanmean: 70.51862335205078
nanmax: 356.5494079589844
Presence of BP > 200
valid: False
Case 7
ABP Shape: (7884967, 1)
nanmin: -495.6260070800781
nanmean: 73.24616241455078
nanmax: 342.7250061035156
Presence of BP > 200
valid: False
Case 10
ABP Shape: (10496246, 1)
nanmin: -495.6260070800781
nanmean: 81.8055191040039
nanmax: 312.1138610839844
Presence of BP > 200
valid: False
Case 12
ABP Shape: (15601485, 1)
nanmin: -495.6260070800781
nanmean: 71.71165466308594
nanmax: 399.0100402832031
>10% NaN
valid: False
Case 13
ABP Shape: (5405555, 1)
nanmin: -495.6260070800781
nanmean: 59.84366226196289
nanmax: 223.24270629882812
Presence of BP > 200
valid: False
Case 16
ABP Shape: (6433641, 1)
nanmin: -495.6260070800781
nanmean: 79.41278839111328
nanmax: 406.9096984863281
Presence of BP > 200
valid: False
Case 19
ABP Shape: (13787741, 1)
nanmin: -495.6260070800781
nanmean: 69.16635131835938
nanmax: 407.8971862792969
Presence of BP > 200
valid: False
Case 20
ABP Shape: (13237788, 1)
nanmin: -495.6260070800781
nanmean: 75.188232421875
nanmax: 305.2016296386719
Presence of BP > 200
valid: False
Case 22
ABP Shape: (7187031, 1)
nanmin: -410.7047119140625
nanmean: 87.6779556274414
nanmax: 407.8971862792969
Presence of BP > 200
valid: False
In [58]:
# free memory
del tmp_abp

Generate Train/Val/Test Splits¶

In [59]:
def get_segment_attributes_from_filename(file_path):
    pieces = os.path.basename(file_path).split('_')
    case = int(pieces[0])
    startX = int(pieces[1])
    predWindow = int(pieces[2])
    label = pieces[3].replace('.h5', '')
    return (case, startX, predWindow, label)
In [60]:
count_negative_samples = 0
count_positive_samples = 0

samples = []

from glob import glob
seg_folder = f"{VITAL_EXTRACTED_SEGMENTS}"
filenames = [y for x in os.walk(seg_folder) for y in glob(os.path.join(x[0], '*.h5'))]

for filename in filenames:
    (case, start_x, pred_window, label) = get_segment_attributes_from_filename(filename)
    #print((case, start_x, pred_window, label))
    
    # only load cases for cases of interest; this folder could have segments for hundreds of cases
    if case not in cases_of_interest_idx:
        continue

    #PREDICTION_WINDOW = 3
    if pred_window == 0 or pred_window == PREDICTION_WINDOW or PREDICTION_WINDOW == 'ALL':
        #print((case, start_x, pred_window, label))
        if label == 'True':
            count_positive_samples += 1
        else:
            count_negative_samples += 1
        sample = (filename, label)
        samples.append(sample)

print()
print(f"samples loaded:         {len(samples):5} ")
print(f'count negative samples: {count_negative_samples:5}')
print(f'count positive samples: {count_positive_samples:5}')
samples loaded:         19676 
count negative samples: 14298
count positive samples:  5378
In [61]:
# Divide by cases
sample_cases = defaultdict(lambda: []) 

for fn, _ in samples:
    (case, start_x, pred_window, label) = get_segment_attributes_from_filename(fn)
    sample_cases[case].append((fn, label))

# understand any missing cases of interest
sample_cases_idx = pd.Index(sample_cases.keys())
missing_case_ids = cases_of_interest_idx.difference(sample_cases_idx)
print(f'cases with no samples: {missing_case_ids.shape[0]}')
print(f'    {missing_case_ids}')
print()
    
# Split data into training, validation, and test sets
# Use 6:1:3 ratio and prevent samples from a single case from being split across different sets
# Note: number of samples at each time point is not the same, because the first event can occur before the 3/5/10/15 minute mark

# Set target sizes
train_ratio = 0.6
val_ratio = 0.1
test_ratio = 1 - train_ratio - val_ratio # ensure ratios sum to 1

# Split samples into train and other
sample_cases_train, sample_cases_other = train_test_split(list(sample_cases.keys()), test_size=(1 - train_ratio), random_state=RANDOM_SEED)

# Split other into val and test
sample_cases_val, sample_cases_test = train_test_split(sample_cases_other, test_size=(test_ratio / (1 - train_ratio)), random_state=RANDOM_SEED)

# Check how many samples are in each set
print(f'Train/Val/Test Summary by Cases')
print(f"Train cases:  {len(sample_cases_train):5}, ({len(sample_cases_train) / len(sample_cases):.2%})")
print(f"Val cases:    {len(sample_cases_val):5}, ({len(sample_cases_val) / len(sample_cases):.2%})")
print(f"Test cases:   {len(sample_cases_test):5}, ({len(sample_cases_test) / len(sample_cases):.2%})")
print(f"Total cases:  {(len(sample_cases_train) + len(sample_cases_val) + len(sample_cases_test)):5}")
cases with no samples: 367
    Index([  26,   49,  126,  139,  149,  152,  172,  199,  200,  203,
       ...
       6271, 6275, 6277, 6293, 6315, 6324, 6360, 6368, 6373, 6388],
      dtype='int64', length=367)

Train/Val/Test Summary by Cases
Train cases:   1645, (59.97%)
Val cases:      274, (9.99%)
Test cases:     824, (30.04%)
Total cases:   2743
In [62]:
sample_cases_train = set(sample_cases_train)
sample_cases_val = set(sample_cases_val)
sample_cases_test = set(sample_cases_test)

samples_train = []
samples_val = []
samples_test = []

for cid, segs in sample_cases.items():
    if cid in sample_cases_train:
        for seg in segs:
            samples_train.append(seg)
    if cid in sample_cases_val:
        for seg in segs:
            samples_val.append(seg)
    if cid in sample_cases_test:
        for seg in segs:
            samples_test.append(seg)
            
# Check how many samples are in each set
print(f'Train/Val/Test Summary by Events')
print(f"Train events:  {len(samples_train):5}, ({len(samples_train) / len(samples):.2%})")
print(f"Val events:    {len(samples_val):5}, ({len(samples_val) / len(samples):.2%})")
print(f"Test events:   {len(samples_test):5}, ({len(samples_test) / len(samples):.2%})")
print(f"Total events:  {(len(samples_train) + len(samples_val) + len(samples_test)):5}")
Train/Val/Test Summary by Events
Train events:  11725, (59.59%)
Val events:     2013, (10.23%)
Test events:    5938, (30.18%)
Total events:  19676

Validate train/val/test Splits¶

In [63]:
PRINT_ALL_CASE_SPLIT_DETAILS = False

case_to_sample_distribution = defaultdict(lambda: {'train': [0, 0], 'val': [0, 0], 'test': [0, 0]})

def populate_case_to_sample_distribution(mysamples, idx):
    neg = 0
    pos = 0
    
    for fn, _ in mysamples:
        (case, start_x, pred_window, label) = get_segment_attributes_from_filename(fn)
        slot = 0 if label == 'False' else 1
        case_to_sample_distribution[case][idx][slot] += 1
        if slot == 0:
            neg += 1
        else:
            pos += 1
                
    return (neg, pos)

train_neg, train_pos = populate_case_to_sample_distribution(samples_train, 'train')
val_neg, val_pos     = populate_case_to_sample_distribution(samples_val,   'val')
test_neg, test_pos   = populate_case_to_sample_distribution(samples_test,  'test')

print(f'Total Cases Present: {len(case_to_sample_distribution):5}')
print()

train_tot = train_pos + train_neg
val_tot = val_pos + val_neg
test_tot = test_pos + test_neg
print(f'Train: P: {train_pos:5} ({(train_pos/train_tot):.2}), N: {train_neg:5} ({(train_neg/train_tot):.2})')
print(f'Val:   P: {val_pos:5} ({(val_pos/val_tot):.2}), N: {val_neg:5} ({(val_neg/val_tot):.2})')
print(f'Test:  P: {test_pos:5} ({(test_pos/test_tot):.2}), N: {test_neg:5}  ({(test_neg/test_tot):.2})')
print()

total_pos = train_pos + val_pos + test_pos
total_neg = train_neg + val_neg + test_neg
total = total_pos + total_neg
print(f'P/N Ratio: {(total_pos)}:{(total_neg)}')
print(f'P Percent: {(total_pos/total):.2}')
print(f'N Percent: {(total_neg/total):.2}')
print()

if PRINT_ALL_CASE_SPLIT_DETAILS:
    for ci in sorted(case_to_sample_distribution.keys()):
        print(f'{ci}: {case_to_sample_distribution[ci]}')
Total Cases Present:  2743

Train: P:  3221 (0.27), N:  8504 (0.73)
Val:   P:   591 (0.29), N:  1422 (0.71)
Test:  P:  1566 (0.26), N:  4372  (0.74)

P/N Ratio: 5378:14298
P Percent: 0.27
N Percent: 0.73

In [64]:
def check_data_leakage(full_data, train_data, val_data, test_data):
    # Convert to sets for easier operations
    full_data_set = set(full_data)
    train_data_set = set(train_data)
    val_data_set = set(val_data)
    test_data_set = set(test_data)

    # Check if train, val, test are subsets of full_data
    if not train_data_set.issubset(full_data_set):
        return "Train data has leakage"
    if not val_data_set.issubset(full_data_set):
        return "Validation data has leakage"
    if not test_data_set.issubset(full_data_set):
        return "Test data has leakage"

    # Check if train, val, test are disjoint
    if train_data_set & val_data_set:
        return "Train and validation data are not disjoint"
    if train_data_set & test_data_set:
        return "Train and test data are not disjoint"
    if val_data_set & test_data_set:
        return "Validation and test data are not disjoint"

    return "No data leakage detected"

# Usage
print(check_data_leakage(list(sample_cases.keys()), sample_cases_train, sample_cases_val, sample_cases_test))
No data leakage detected
In [65]:
# Create vitalDataset class
class vitalDataset(Dataset):
    def __init__(self, samples, normalize_abp=False):
        self.samples = samples
        self.normalize_abp = normalize_abp

    def __len__(self):
        return len(self.samples)

    def __getitem__(self, idx):
        # Get metadata for this event
        segment = self.samples[idx]

        file_path = segment[0]
        label = (segment[1] == "True" or segment[1] == "True.vital")

        (abp, ecg, eeg) = get_segment_data(file_path)

        if abp is None or eeg is None or ecg is None:
            return (np.zeros(30000), np.zeros(30000), np.zeros(7680), 0)
        
        if self.normalize_abp:
            abp -= 65
            abp /= 65

        return abp, ecg, eeg, label
In [66]:
NORMALIZE_ABP = False

train_dataset = vitalDataset(samples_train, NORMALIZE_ABP)
val_dataset = vitalDataset(samples_val, NORMALIZE_ABP)
test_dataset = vitalDataset(samples_test, NORMALIZE_ABP)

train/val/test Splits Summary Statistics¶

In [67]:
def generate_nan_means(mydataset):
    xs = np.zeros(len(mydataset))
    ys = np.zeros(len(mydataset), dtype=int)

    for i, (abp, ecg, eeg, y) in enumerate(iter(mydataset)):
        xs[i] = np.nanmean(abp)
        ys[i] = int(y)

    return pd.DataFrame({'abp_nanmean': xs, 'label': ys})
In [68]:
def generate_nan_means_summaries(tr, va, te, group='all'):
    if group == 'all':
        return pd.DataFrame({
            'train': tr.describe()['abp_nanmean'],
            'validation': va.describe()['abp_nanmean'],
            'test': te.describe()['abp_nanmean']
        })
    
    mytr = tr.reset_index()
    myva = va.reset_index()
    myte = te.reset_index()
    
    label_flag = True if group == 'positive' else False
    
    return pd.DataFrame({
        'train':      mytr[mytr['label'] == label_flag].describe()['abp_nanmean'],
        'validation': myva[myva['label'] == label_flag].describe()['abp_nanmean'],
        'test':       myte[myte['label'] == label_flag].describe()['abp_nanmean']
    })
In [69]:
def plot_nan_means(df, plot_label):
    mydf = df.reset_index()

    maxCases = 'ALL' if MAX_CASES is None else MAX_CASES
    plot_title = f'{plot_label} - ABP nanmean Values, {PREDICTION_WINDOW} Minutes, {maxCases} Cases'
    
    ax = mydf[mydf['label'] == False].plot.scatter(
        x='index', y='abp_nanmean', color='DarkBlue', label='Negative', 
        title=plot_title, figsize=(16,9))

    negative_median = mydf[mydf['label'] == False]['abp_nanmean'].median()
    ax.axhline(y=negative_median, color='DarkBlue', linestyle='--', label='Negative Median')
    
    mydf[mydf['label'] == True].plot.scatter(
        x='index', y='abp_nanmean', color='DarkOrange', label='Positive', ax=ax);
    
    positive_median = mydf[mydf['label'] == True]['abp_nanmean'].median()
    ax.axhline(y=positive_median, color='DarkOrange', linestyle='--', label='Positive Median')
    
    ax.legend(loc='upper right')
In [70]:
def plot_nan_means_hist(df):
    df.plot.hist(column=['abp_nanmean'], by='label', bins=50, figsize=(10, 8));
In [71]:
train_abp_nanmeans = generate_nan_means(train_dataset)
val_abp_nanmeans = generate_nan_means(val_dataset)
test_abp_nanmeans = generate_nan_means(test_dataset)

ABP Nanmean Summaries¶

In [72]:
generate_nan_means_summaries(train_abp_nanmeans, val_abp_nanmeans, test_abp_nanmeans)
Out[72]:
train validation test
count 11725.000000 2013.000000 5938.000000
mean 85.342557 84.527469 85.337452
std 12.102408 11.928181 12.139388
min 65.136129 65.176681 65.178063
25% 75.843523 75.141869 75.794924
50% 83.549179 82.839065 83.643432
75% 93.382970 92.584281 92.977931
max 138.285504 131.649859 147.949437
In [73]:
generate_nan_means_summaries(train_abp_nanmeans, val_abp_nanmeans, test_abp_nanmeans, group='positive')
Out[73]:
train validation test
count 3221.000000 591.000000 1566.000000
mean 76.393673 75.830934 76.462263
std 9.120690 8.735726 9.256418
min 65.136129 65.176681 65.178063
25% 70.014729 69.719051 69.994147
50% 74.056950 73.944380 74.136967
75% 80.011449 79.447594 80.095860
max 132.143619 124.815472 136.381225
In [74]:
generate_nan_means_summaries(train_abp_nanmeans, val_abp_nanmeans, test_abp_nanmeans, group='negative')
Out[74]:
train validation test
count 8504.000000 1422.000000 4372.000000
mean 88.732062 88.141852 88.516442
std 11.341231 11.191253 11.452285
min 65.225560 66.221575 65.476802
25% 80.095975 79.646864 79.987240
50% 87.345195 86.884530 87.118146
75% 95.959147 95.516197 95.679384
max 138.285504 131.649859 147.949437

ABP Nanmean Histograms¶

In [75]:
plot_nan_means_hist(train_abp_nanmeans)
In [76]:
plot_nan_means_hist(val_abp_nanmeans)
In [77]:
plot_nan_means_hist(test_abp_nanmeans)

ABP Nanmean Scatter Plots¶

In [78]:
plot_nan_means(train_abp_nanmeans, 'Train')
In [79]:
plot_nan_means(val_abp_nanmeans, 'Validation')
In [80]:
plot_nan_means(test_abp_nanmeans, 'Test')
In [81]:
# Cleanup
del train_abp_nanmeans
del val_abp_nanmeans
del test_abp_nanmeans

Classification Studies¶

Check if data can be easily classified using non-deep learning methods. Create a balanced sample of IOH and non-IOH events and use a simple classifier to see if the data can be easily separated. Datasets which can be easily separated by non-deep learning methods should also be easily classified by deep learning models.

In [82]:
MAX_CLASSIFICATION_SAMPLES = 250
MAX_SAMPLE_SIZE = 1600
classification_sample_size = MAX_SAMPLE_SIZE if len(samples) >= MAX_SAMPLE_SIZE else len(samples)

classification_samples = random.sample(samples, classification_sample_size)

positive_samples = []
negative_samples = []

for sample in classification_samples:
    (sampleAbp, sampleEcg, sampleEeg) = get_segment_data(sample[0])
    
    if sample[1] == "True":
        positive_samples.append([sample[0], True, sampleAbp, sampleEcg, sampleEeg])
    else:
        negative_samples.append([sample[0], False, sampleAbp, sampleEcg, sampleEeg])

positive_samples = pd.DataFrame(positive_samples, columns=["file_path", "segment_label", "segment_abp", "segment_ecg", "segment_eeg"])
negative_samples = pd.DataFrame(negative_samples, columns=["file_path", "segment_label", "segment_abp", "segment_ecg", "segment_eeg"])

total_to_sample_pos = MAX_CLASSIFICATION_SAMPLES if len(positive_samples) >= MAX_CLASSIFICATION_SAMPLES else len(positive_samples)
total_to_sample_neg = MAX_CLASSIFICATION_SAMPLES if len(negative_samples) >= MAX_CLASSIFICATION_SAMPLES else len(negative_samples)

# Select up to 150 random samples where segment_label is True
positive_samples = positive_samples.sample(total_to_sample_pos, random_state=RANDOM_SEED)
# Select up to 150 random samples where segment_label is False
negative_samples = negative_samples.sample(total_to_sample_neg, random_state=RANDOM_SEED)

print(f'positive_samples: {len(positive_samples)}')
print(f'negative_samples: {len(negative_samples)}')

# Combine the positive and negative samples
samples_balanced = pd.concat([positive_samples, negative_samples])
positive_samples: 250
negative_samples: 250

Define function to build data for study. Each waveform field can be enabled or disabled:

In [83]:
def get_x_y(samples, use_abp, use_ecg, use_eeg):
    # Create X and y, using data from `samples_balanced` and the `use_abp`, `use_ecg`, and `use_eeg` variables
    X = []
    y = []
    for i in range(len(samples)):
        row = samples.iloc[i]
        sample = np.array([])
        if use_abp:
            if len(row['segment_abp']) != 30000:
                print(len(row['segment_abp']))
            sample = np.append(sample, row['segment_abp'])
        if use_ecg:
            if len(row['segment_ecg']) != 30000:
                print(len(row['segment_ecg']))
            sample = np.append(sample, row['segment_ecg'])
        if use_eeg:
            if len(row['segment_eeg']) != 7680:
                print(len(row['segment_eeg']))
            sample = np.append(sample, row['segment_eeg'])
        X.append(sample)
        # Convert the label from boolean to 0 or 1
        y.append(int(row['segment_label']))
    return X, y

KNN¶

Define KNN run. This is configurable to enable or disable different data channels so that we can study them individually or together:

In [84]:
N_NEIGHBORS = 20

def run_knn(samples, use_abp, use_ecg, use_eeg):
    # Get samples
    X,y = get_x_y(samples, use_abp, use_ecg, use_eeg)

    # Split samples into train and val
    knn_X_train, knn_X_test, knn_y_train, knn_y_test = train_test_split(X, y, test_size=0.2, random_state=RANDOM_SEED)

    # Normalize the data
    scaler = StandardScaler()
    scaler.fit(knn_X_train)

    knn_X_train = scaler.transform(knn_X_train)
    knn_X_test = scaler.transform(knn_X_test)

    # Initialize the KNN classifier
    knn = KNeighborsClassifier(n_neighbors=N_NEIGHBORS)

    # Train the KNN classifier
    knn.fit(knn_X_train, knn_y_train)

    # Make predictions on the test set
    knn_y_pred = knn.predict(knn_X_test)

    # Evaluate the KNN classifier
    print(f"ABP: {use_abp}, ECG: {use_ecg}, EEG: {use_eeg}")
    print(f"Confusion matrix:\n{confusion_matrix(knn_y_test, knn_y_pred)}")
    print(f"Classification report:\n{classification_report(knn_y_test, knn_y_pred)}")

Study each waveform independently, then ABP+EEG (which had best results in paper), and ABP+ECG+EEG:

In [85]:
run_knn(samples_balanced, use_abp=True, use_ecg=False, use_eeg=False)
run_knn(samples_balanced, use_abp=False, use_ecg=True, use_eeg=False)
run_knn(samples_balanced, use_abp=False, use_ecg=False, use_eeg=True)
run_knn(samples_balanced, use_abp=True, use_ecg=False, use_eeg=True)
run_knn(samples_balanced, use_abp=True, use_ecg=True, use_eeg=True)
ABP: True, ECG: False, EEG: False
Confusion matrix:
[[48  6]
 [16 30]]
Classification report:
              precision    recall  f1-score   support

           0       0.75      0.89      0.81        54
           1       0.83      0.65      0.73        46

    accuracy                           0.78       100
   macro avg       0.79      0.77      0.77       100
weighted avg       0.79      0.78      0.78       100

ABP: False, ECG: True, EEG: False
Confusion matrix:
[[32 22]
 [21 25]]
Classification report:
              precision    recall  f1-score   support

           0       0.60      0.59      0.60        54
           1       0.53      0.54      0.54        46

    accuracy                           0.57       100
   macro avg       0.57      0.57      0.57       100
weighted avg       0.57      0.57      0.57       100

ABP: False, ECG: False, EEG: True
Confusion matrix:
[[ 2 52]
 [ 0 46]]
Classification report:
              precision    recall  f1-score   support

           0       1.00      0.04      0.07        54
           1       0.47      1.00      0.64        46

    accuracy                           0.48       100
   macro avg       0.73      0.52      0.36       100
weighted avg       0.76      0.48      0.33       100

ABP: True, ECG: False, EEG: True
Confusion matrix:
[[42 12]
 [ 7 39]]
Classification report:
              precision    recall  f1-score   support

           0       0.86      0.78      0.82        54
           1       0.76      0.85      0.80        46

    accuracy                           0.81       100
   macro avg       0.81      0.81      0.81       100
weighted avg       0.81      0.81      0.81       100

ABP: True, ECG: True, EEG: True
Confusion matrix:
[[39 15]
 [ 6 40]]
Classification report:
              precision    recall  f1-score   support

           0       0.87      0.72      0.79        54
           1       0.73      0.87      0.79        46

    accuracy                           0.79       100
   macro avg       0.80      0.80      0.79       100
weighted avg       0.80      0.79      0.79       100

Based on the data above, the ABP data alone is strongly predictive based on the macro average F1-score of 0.90. The ECG and EEG data are weakly predictive with F1 scores of 0.33 and 0.64, respectively. The ABP+EEG data is also strongly predictive with an F1 score of 0.88, and ABP+ECG+EEG data somewhat predictive with an F1 score of 0.79.

Models based on ABP data alone, or ABP+EEG data are expected to train easily with good performance. The other signals appear to mostly add noise and are not strongly predictive. This agrees with the results from the paper.

t-SNE¶

Define t-SNE run. This is configurable to enable or disable different data channels so that we can study them individually or together:

In [86]:
def run_tsne(samples, use_abp, use_ecg, use_eeg):
    # Get samples
    X,y = get_x_y(samples, use_abp, use_ecg, use_eeg)
    
    # Convert X and y to numpy arrays
    X = np.array(X)
    y = np.array(y)

    # Run t-SNE on the samples
    tsne = TSNE(n_components=len(np.unique(y)), random_state=RANDOM_SEED)
    X_tsne = tsne.fit_transform(X)
    
    # Create a scatter plot of the t-SNE representation
    plt.figure(figsize=(16, 9))
    plt.title(f"use_abp={use_abp}, use_ecg={use_ecg}, use_eeg={use_eeg}")
    for i, label in enumerate(set(y)):
        plt.scatter(X_tsne[y == label, 0], X_tsne[y == label, 1], label=label)
    plt.legend()
    plt.show()

Study each waveform independently, then ABP+EEG (which had best results in paper), and ABP+ECG+EEG:

In [87]:
run_tsne(samples_balanced, use_abp=True, use_ecg=False, use_eeg=False)
run_tsne(samples_balanced, use_abp=False, use_ecg=True, use_eeg=False)
run_tsne(samples_balanced, use_abp=False, use_ecg=False, use_eeg=True)
run_tsne(samples_balanced, use_abp=True, use_ecg=False, use_eeg=True)
run_tsne(samples_balanced, use_abp=True, use_ecg=True, use_eeg=True)

Based on the plots above, it appears that ABP alone, ABP+EEG and ABP+ECG+EEG are somewhat separable, though with outliers, and should be trainable by our model. The ECG and EEG data are not easily separable from the other data. This agrees with the results from the paper.

In [88]:
# cleanup
del samples_balanced

Model¶

The model implementation is based on the CNN architecture described in Jo Y-Y et al. (2022). It is designed to handle 1, 2, or 3 signal categories simultaneously, allowing for flexible model configurations based on different combinations of physiological signals:

  • ABP alone
  • EEG alone
  • ECG alone
  • ABP + EEG
  • ABP + ECG
  • EEG + ECG
  • ABP + EEG + ECG

Model Architecture¶

The architecture, as depicted in Figure 2 from the original paper, utilizes a ResNet-based approach tailored for time-series data from different physiological signals. The model architecture is adapted to handle varying input signal frequencies, with specific hyperparameters for each signal type, particularly EEG, due to its distinct characteristics compared to ABP and ECG. A diagram of the model architecture is shown below:

Architecture of the hypotension risk prediction model using multiple waveforms

Each input signal is processed through a sequence of 12 7-layer residual blocks, followed by a flattening process and a linear transformation to produce a 32-dimensional feature vector per signal type. These vectors are then concatenated (if multiple signals are used) and passed through two additional linear layers to produce a single output vector, representing the IOH index. A threshold is determined experimentally in order to minimize the differene between the sensitivity and specificity and is applied to this index to perform binary classification for predicting IOH events.

The hyperparameters for the residual blocks are specified in Supplemental Table 1 from the original paper and vary for different signal type.

A forward pass through the model passes through 85 layers before concatenation, followed by two more linear layers and finally a sigmoid activation layer to produce the prediction measure.

Residual Block Definition¶

Each residual block consists of the following seven layers:

  • Batch normalization
  • ReLU
  • Dropout (0.5)
  • 1D convolution
  • Batch normalization
  • ReLU
  • 1D convolution

Skip connections are included to aid in gradient flow during training, with optional 1D convolution in the skip connection to align dimensions.

Residual Block Hyperparameters¶

The hyperparameters are detailed in Supplemental Table 1 of the original paper. A screenshot of these hyperparameters is provided for reference below:

Supplemental Table 1 from original paper

Note: Please be aware of a transcription error in the original paper's Supplemental Table 1 for the ECG+ABP configuration in Residual Blocks 11 and 12, where the output size should be 469 6 instead of the reported 496 6.

Training Objectives¶

Our model uses binary cross entropy as the loss function and Adam as the optimizer, consistent with the original study. The learning rate is set at 0.0001, and training is configured to run for up to 100 epochs, with early stopping implemented if no improvement in loss is observed over five consecutive epochs.

In [89]:
# First define the residual block which is reused 12x for each data track for each sample.
# Second define the primary model.
class ResidualBlock(nn.Module):
    def __init__(self, in_features: int, out_features: int, in_channels: int, out_channels: int, kernel_size: int, stride: int = 1, size_down: bool = False, ignoreSkipConnection: bool = False) -> None:
        super(ResidualBlock, self).__init__()
        
        self.ignoreSkipConnection = ignoreSkipConnection

        # calculate the appropriate padding required to ensure expected sequence lengths out of each residual block
        padding = int((((stride-1)*in_features)-stride+kernel_size)/2)

        self.size_down = size_down
        self.bn1 = nn.BatchNorm1d(in_channels)
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(0.5)
        self.conv1 = nn.Conv1d(in_channels, out_channels, kernel_size=kernel_size, stride=1, padding=padding, bias=False)
        self.bn2 = nn.BatchNorm1d(out_channels)
        self.conv2 = nn.Conv1d(out_channels, out_channels, kernel_size=kernel_size, stride=1, padding=padding, bias=False)
        
        self.residualConv = nn.Conv1d(in_channels, out_channels, kernel_size=kernel_size, stride=1, padding=padding, bias=False)

        # unclear where in sequence this should take place. Size down expressed in Supplemental table S1
        if self.size_down:
            pool_padding = (1 if (in_features % 2 > 0) else 0)
            self.downsample = nn.MaxPool1d(kernel_size=2, stride=2, padding = pool_padding)
        
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        identity = x
        
        out = self.bn1(x)
        out = self.relu(out)
        out = self.dropout(out)
        out = self.conv1(out)

        if self.size_down:
            out = self.downsample(out)

        out = self.bn2(out)
        out = self.relu(out)
        out = self.conv2(out)
        
        if not self.ignoreSkipConnection:
          if out.shape != identity.shape:
              # run the residual through a convolution when necessary
              identity = self.residualConv(identity)
            
              outlen = np.prod(out.shape)
              idlen = np.prod(identity.shape)
              # downsample when required
              if idlen > outlen:
                  identity = self.downsample(identity)
              # match dimensions
              identity = identity.reshape(out.shape)

          # add the residual       
          out += identity

        return  out

class HypotensionCNN(nn.Module):
    def __init__(self, useAbp: bool = True, useEeg: bool = False, useEcg: bool = False, device: str = "cpu", nResiduals: int = 12, ignoreSkipConnection: bool = False, useSigmoid: bool = True) -> None:
        assert useAbp or useEeg or useEcg, "At least one data track must be used"
        assert nResiduals > 0 and nResiduals <= 12, "Number of residual blocks must be between 1 and 12"
        super(HypotensionCNN, self).__init__()

        self.device = device

        self.useAbp = useAbp
        self.useEeg = useEeg
        self.useEcg = useEcg
        self.nResiduals = nResiduals
        self.useSigmoid = useSigmoid

        # Size of the concatenated output from the residual blocks
        concatSize = 0

        if useAbp:
          self.abpBlocks = []
          self.abpMultipliers = [1, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6]
          self.abpSizes = [30000, 15000, 15000, 7500, 7500, 3750, 3750, 1875, 1875, 938, 938, 469, 469]
          for i in range(self.nResiduals):
            downsample = i % 2 == 0
            self.abpBlocks.append(ResidualBlock(self.abpSizes[i], self.abpSizes[i+1], self.abpMultipliers[i], self.abpMultipliers[i+1], 15 if i < 6 else 7, 1, downsample, ignoreSkipConnection))
          self.abpResiduals = nn.Sequential(*self.abpBlocks)
          self.abpFc = nn.Linear(self.abpMultipliers[self.nResiduals] * self.abpSizes[self.nResiduals], 32)
          concatSize += 32
        
        if useEcg:
          self.ecgBlocks = []
          self.ecgMultipliers = [1, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6]
          self.ecgSizes = [30000, 15000, 15000, 7500, 7500, 3750, 3750, 1875, 1875, 938, 938, 469, 469]

          for i in range(self.nResiduals):
            downsample = i % 2 == 0
            self.ecgBlocks.append(ResidualBlock(self.ecgSizes[i], self.ecgSizes[i+1], self.ecgMultipliers[i], self.ecgMultipliers[i+1], 15 if i < 6 else 7, 1, downsample, ignoreSkipConnection))
          self.ecgResiduals = nn.Sequential(*self.ecgBlocks)
          self.ecgFc = nn.Linear(self.ecgMultipliers[self.nResiduals] * self.ecgSizes[self.nResiduals], 32)
          concatSize += 32

        if useEeg:
          self.eegBlocks = []
          self.eegMultipliers = [1, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6]
          self.eegSizes = [7680, 3840, 3840, 1920, 1920, 960, 960, 480, 480, 240, 240, 120, 120]

          for i in range(self.nResiduals):
            downsample = i % 2 == 0
            self.eegBlocks.append(ResidualBlock(self.eegSizes[i], self.eegSizes[i+1], self.eegMultipliers[i], self.eegMultipliers[i+1], 7 if i < 6 else 3, 1, downsample, ignoreSkipConnection))
          self.eegResiduals = nn.Sequential(*self.eegBlocks)
          self.eegFc = nn.Linear(self.eegMultipliers[self.nResiduals] * self.eegSizes[self.nResiduals], 32)
          concatSize += 32

        self.fullLinear1 = nn.Linear(concatSize, 16)
        self.fullLinear2 = nn.Linear(16, 1)
        self.sigmoid = nn.Sigmoid()


    def forward(self, abp: torch.Tensor, eeg: torch.Tensor, ecg: torch.Tensor) -> torch.Tensor:
        batchSize = len(abp)

        # conditionally operate ABP, EEG, and ECG networks
        tensors = []
        if self.useAbp:
          self.abpResiduals.to(self.device)
          abp = self.abpResiduals(abp)
          totalLen = np.prod(abp.shape)
          abp = torch.reshape(abp, (batchSize, int(totalLen / batchSize)))
          abp = self.abpFc(abp)
          tensors.append(abp)

        if self.useEeg:
          self.eegResiduals.to(self.device)
          eeg = self.eegResiduals(eeg)
          totalLen = np.prod(eeg.shape)
          eeg = torch.reshape(eeg, (batchSize, int(totalLen / batchSize)))
          eeg = self.eegFc(eeg)
          tensors.append(eeg)
        
        if self.useEcg:
          self.ecgResiduals.to(self.device)
          ecg = self.ecgResiduals(ecg)
          totalLen = np.prod(ecg.shape)
          ecg = torch.reshape(ecg, (batchSize, int(totalLen / batchSize)))
          ecg = self.ecgFc(ecg)
          tensors.append(ecg)

        # concatenate the tensors along dimension 1 if there's more than one, otherwise use the single tensor
        merged = torch.cat(tensors, dim=1) if len(tensors) > 1 else tensors[0]

        totalLen = np.prod(merged.shape)
        merged = torch.reshape(merged, (batchSize, int(totalLen / batchSize)))
        out = self.fullLinear1(merged)
        out = self.fullLinear2(out)
        if self.useSigmoid:
            out = self.sigmoid(out)

        # We should not be seeing NaNs! If we are, there is a problem upstream.
        #out = torch.nan_to_num(out)
        return out

Training¶

As discussed earlier, our model uses binary cross entropy as the loss function and Adam as the optimizer, consistent with the original study. The learning rate is set at 0.0001, and training is configured to run for up to 100 epochs, with early stopping implemented if no improvement in loss is observed over five consecutive epochs.

In [90]:
def train_model_one_iter(model, device, loss_func, optimizer, train_loader):
    model.train()
    train_losses = []
    
    for abp, ecg, eeg, label in tqdm(train_loader):
        batch = len(abp)
        abp = abp.reshape(batch, 1, -1).type(torch.FloatTensor).to(device)
        ecg = ecg.reshape(batch, 1, -1).type(torch.FloatTensor).to(device)
        eeg = eeg.reshape(batch, 1, -1).type(torch.FloatTensor).to(device)
        label = label.type(torch.float).reshape(batch, 1).to(device)

        optimizer.zero_grad()
        mdl = model(abp, eeg, ecg)
        loss = loss_func(torch.nan_to_num(mdl), label)
        loss.backward()
        optimizer.step()
        train_losses.append(loss.cpu().data.numpy())
    return np.mean(train_losses)
In [91]:
def evaluate_model(model, loss_func, val_loader):
    model.eval()
    val_losses = []
    for abp, ecg, eeg, label in tqdm(val_loader):
        batch = len(abp)

        abp = abp.reshape(batch, 1, -1).type(torch.FloatTensor).to(device)
        ecg = ecg.reshape(batch, 1, -1).type(torch.FloatTensor).to(device)
        eeg = eeg.reshape(batch, 1, -1).type(torch.FloatTensor).to(device)
        label = label.type(torch.float).reshape(batch, 1).to(device)

        mdl = model(abp, eeg, ecg)
        loss = loss_func(torch.nan_to_num(mdl), label)
        val_losses.append(loss.cpu().data.numpy())
    return np.mean(val_losses)
In [92]:
def plot_losses(train_losses, val_losses, best_epoch, experimentName):
    print()
    print(f'Plot Validation and Loss Values from Training')
    print(f'  Epoch with best Validation Loss:  {best_epoch:3}, {val_losses[best_epoch]:.4}')

    # Create x-axis values for epochs
    epochs = range(0, len(train_losses))

    plt.figure(figsize=(16, 9))

    # Plot the training and validation losses
    plt.plot(epochs, train_losses, 'b', label='Training Loss')
    plt.plot(epochs, val_losses, 'r', label='Validation Loss')

    # Add a vertical bar at the best_epoch
    plt.axvline(x=best_epoch, color='g', linestyle='--', label='Best Epoch')

    # Shade everything to the right of the best_epoch a light red
    plt.axvspan(best_epoch, max(epochs), facecolor='r', alpha=0.1)

    # Add labels and title
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.title(experimentName)

    # Add legend
    plt.legend(loc='upper right')

    # Show the plot
    plt.show()
In [93]:
def eval_model(model, device, dataloader, loss_func, print_detailed: bool = False):
    model.eval()
    model = model.to(device)
    total_loss = 0
    all_predictions = []
    all_labels = []

    with torch.no_grad():
        for abp, ecg, eeg, label in tqdm(dataloader):
            batch = len(abp)
    
            abp = torch.nan_to_num(abp.reshape(batch, 1, -1)).type(torch.FloatTensor).to(device)
            ecg = torch.nan_to_num(ecg.reshape(batch, 1, -1)).type(torch.FloatTensor).to(device)
            eeg = torch.nan_to_num(eeg.reshape(batch, 1, -1)).type(torch.FloatTensor).to(device)
            label = label.type(torch.float).reshape(batch, 1).to(device)
   
            pred = model(abp, eeg, ecg)
            loss = loss_func(pred, label)
            total_loss += loss.item()

            all_predictions.append(pred.detach().cpu().numpy())
            all_labels.append(label.detach().cpu().numpy())

    # Flatten the lists
    all_predictions = np.concatenate(all_predictions).flatten()
    all_labels = np.concatenate(all_labels).flatten()

    # Calculate AUROC and AUPRC
    # y_true, y_pred
    auroc = roc_auc_score(all_labels, all_predictions)
    precision, recall, _ = precision_recall_curve(all_labels, all_predictions)
    auprc = auc(recall, precision)

    # Determine the optimal threshold, which is argmin(abs(sensitivity - specificity)) per the paper
    thresholds = np.linspace(0, 1, 101) # 0 to 1 in 0.01 steps
    min_diff = float('inf')
    optimal_sensitivity = None
    optimal_specificity = None
    optimal_threshold = None

    for threshold in thresholds:
        all_predictions_binary = (all_predictions > threshold).astype(int)

        tn, fp, fn, tp = confusion_matrix(all_labels, all_predictions_binary).ravel()
        sensitivity = tp / (tp + fn)
        specificity = tn / (tn + fp)
        diff = abs(sensitivity - specificity)

        if diff < min_diff:
            min_diff = diff
            optimal_threshold = threshold
            optimal_sensitivity = sensitivity
            optimal_specificity = specificity

    avg_loss = total_loss / len(dataloader)

    if print_detailed:
        print(f"Predictions: {all_predictions}")
        print(f"Labels: {all_labels}")
    print(f"Loss: {avg_loss}")
    print(f"AUROC: {auroc}")
    print(f"AUPRC: {auprc}")
    print(f"Sensitivity: {optimal_sensitivity}")
    print(f"Specificity: {optimal_specificity}")
    print(f"Threshold: {optimal_threshold}")

    return all_predictions, all_labels, avg_loss, auroc, auprc, optimal_sensitivity, optimal_specificity, optimal_threshold
In [94]:
def print_all_evals(model, models, device, val_loader, test_loader, loss_func, print_detailed: bool = False):
    print()
    print(f'Generate AUROC/AUPRC for Each Intermediate Model')
    print()
    val_aurocs = []
    val_auprcs = []

    test_aurocs = []
    test_auprcs = []

    for mod in models:
        model.load_state_dict(torch.load(mod))
        model.train(False)
        print(f'Intermediate Model:')
        print(f'  {mod}')
    
        # validation loop
        print("AUROC/AUPRC on Validation Data")
        _, _, _, valid_auroc, valid_auprc, _, _, _ = \
            eval_model(model, device, val_loader, loss_func, print_detailed)
        
        val_aurocs.append(valid_auroc)
        val_auprcs.append(valid_auprc)
        print()
    
        # test loop
        print("AUROC/AUPRC on Test Data")
        _, _, _, test_auroc, test_auprc, _, _, _ = \
            eval_model(model, device, test_loader, loss_func, print_detailed)
        
        test_aurocs.append(test_auroc)
        test_auprcs.append(test_auprc)
        print()
    
    return val_aurocs, val_auprcs, test_aurocs, test_auprcs
In [95]:
def plot_auroc_auprc(val_losses, val_aurocs, val_auprcs, test_aurocs, test_auprcs, all_models, best_epoch):
    print()
    print(f'Plot AUROC/AUPRC for Each Intermediate Model')
    
    # Create x-axis values for epochs
    epochs = range(0, len(val_aurocs))

    # Find model with highest AUROC
    np_test_aurocs = np.array(test_aurocs)
    test_auroc_idx = np.argmax(np_test_aurocs)

    print(f'  Epoch with best Validation Loss:  {best_epoch:3}, {val_losses[best_epoch]:.4}')
    print(f'  Epoch with best model Test AUROC: {test_auroc_idx:3}, {np.max(np_test_aurocs):.4}')
    #print(f'Best Model on Validation Loss:')
    #print(f'  {all_models[test_auroc_idx]}')
    #print(f'Best Model on Test AUROC:')
    #print(f'  {all_models[best_epoch]}')

    plt.figure(figsize=(16, 9))

    # Plot the training and validation losses
    plt.plot(epochs, val_aurocs, 'C0', label='AUROC - Validation')
    plt.plot(epochs, test_aurocs, 'C1', label='AUROC - Test')

    plt.plot(epochs, val_auprcs, 'C2', label='AUPRC - Validation')
    plt.plot(epochs, test_auprcs, 'C3', label='AUPRC - Test')

    # Add a vertical bar at the best_epoch
    plt.axvline(x=best_epoch, color='g', linestyle='--', label='Best Epoch - Validation Loss')
    plt.axvline(x=test_auroc_idx, color='maroon', linestyle='--', label='Best Epoch - Test AUROC')

    # Shade everything to the right of the best_model a light red
    plt.axvspan(test_auroc_idx, max(epochs), facecolor='r', alpha=0.1)

    # Add labels and title
    plt.xlabel('Epochs')
    plt.ylabel('AUROC / AUPRC')
    plt.title('Validation and Test AUROC by Model Iteration Across Training')

    # Add legend
    plt.legend(loc='right')

    # Show the plot
    plt.show()

    return np_test_aurocs, test_auroc_idx
In [96]:
def run_experiment(
    experimentNamePrefix: str = None,
    useAbp: bool = True, 
    useEeg: bool = False, 
    useEcg: bool = False, 
    nResiduals: int = 12, 
    skip_connection: bool = False, 
    batch_size: int = 64, 
    learning_rate: float = 1e-4, 
    weight_decay: float = 0.0, 
    balance_labels: bool = False,
    pos_weight: float = None,
    max_epochs: int = 100, 
    patience: int = 25, 
    device: str = "cpu"
):
    experimentName = ""

    experimentOptions = [experimentNamePrefix, 'ABP', 'EEG', 'ECG', 'SKIPCONNECTION']
    experimentValues = [experimentNamePrefix is not None, useAbp, useEeg, useEcg, skip_connection]
    experimentFlags = [name for name, value in zip(experimentOptions, experimentValues) if value]
    if experimentFlags:
        experimentName = "_".join(experimentFlags)

    experimentName = f"{experimentName}_{nResiduals}_RESIDUAL_BLOCKS_{batch_size}_BATCH_SIZE_{learning_rate}_LEARNING_RATE"

    if weight_decay is not None and weight_decay != 0.0:
        experimentName = f"{experimentName}_{weight_decay}_WEIGHT_DECAY"

    predictionWindow = 'ALL' if PREDICTION_WINDOW == 'ALL' else f'{PREDICTION_WINDOW:03}'
    experimentName = f"{experimentName}_{predictionWindow}_MINS"

    maxCases = '_ALL' if MAX_CASES is None else f'{MAX_CASES:04}'
    experimentName = f"{experimentName}_{maxCases}_MAX_CASES"
    
    # default label split based on empirical data
    my_pos_weight = 4.0
    if balance_labels and pos_weight is not None:
        my_pos_weight = pos_weight

    print(f"Experiment Setup")
    print(f'  name:              {experimentName}')
    print(f'  prediction_window: {predictionWindow}')
    print(f'  max_cases:         {maxCases}')
    print(f'  use_abp:           {useAbp}')
    print(f'  use_eeg:           {useEeg}')
    print(f'  use_ecg:           {useEcg}')
    print(f'  n_residuals:       {nResiduals}')
    print(f'  skip_connection:   {skip_connection}')
    print(f'  batch_size:        {batch_size}')
    print(f'  learning_rate:     {learning_rate}')
    print(f'  weight_decay:      {weight_decay}')
    print(f'  balance_labels:    {balance_labels}')
    if balance_labels:
        print(f'  pos_weight:        {my_pos_weight}')
    print(f'  max_epochs:        {max_epochs}')
    print(f'  patience:          {patience}')
    print(f'  device:            {device}')
    print()

    train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    val_loader = torch.utils.data.DataLoader(val_dataset, batch_size=batch_size, shuffle=True)
    test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

    # Disable final sigmoid activation for BCEWithLogitsLoss
    model = HypotensionCNN(useAbp, useEeg, useEcg, device, nResiduals, skip_connection, useSigmoid=(not balance_labels))
    model = model.to(device)
    
    if balance_labels:
        # Only the weight for the positive class
        loss_func = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([my_pos_weight]).to(device))
    else:
        loss_func = nn.BCELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=weight_decay)

    
    print(f'Model Architecture')
    print(model)
    print()

    print(f'Training Loop')
    # Training loop
    best_epoch = 0
    train_losses = []
    val_losses = []
    best_loss = float('inf')
    no_improve_epochs = 0
    model_path = os.path.join(VITAL_MODELS, f"{experimentName}.model")

    all_models = []

    for i in range(max_epochs):
        # Train the model and get the training loss
        train_loss = train_model_one_iter(model, device, loss_func, optimizer, train_loader)
        train_losses.append(train_loss)
        # Calculate validate loss
        val_loss = evaluate_model(model, loss_func, val_loader)
        val_losses.append(val_loss)
        print(f"[{datetime.now()}] Completed epoch {i} with training loss {train_loss:.8f}, validation loss {val_loss:.8f}")

        # Save all intermediary models.
        tmp_model_path = os.path.join(VITAL_MODELS, f"{experimentName}_{i:04d}.model")
        torch.save(model.state_dict(), tmp_model_path)
        all_models.append(tmp_model_path)
  
        # Check if validation loss has improved
        if val_loss < best_loss:
            best_epoch = i
            best_loss = val_loss
            no_improve_epochs = 0
            torch.save(model.state_dict(), model_path)
            print(f"Validation loss improved to {val_loss:.8f}. Model saved.")
        else:
            no_improve_epochs += 1
            print(f"No improvement in validation loss. {no_improve_epochs} epochs without improvement.")

        # exit early if no improvement in loss over last 'patience' epochs
        if no_improve_epochs >= patience:
            print("Early stopping due to no improvement in validation loss.")
            break

    # Load best model from disk
    #print()
    #if os.path.exists(model_path):
    #    model.load_state_dict(torch.load(model_path))
    #    print(f"Loaded best model from disk from epoch {best_epoch}.")
    #else:
    #    print("No saved model found for f{experimentName}.")

    model.train(False)

    # Plot the training and validation losses across all training epochs.
    plot_losses(train_losses, val_losses, best_epoch, experimentName)

    # Generate AUROC/AUPRC for each intermediate model generated across training epochs.
    val_aurocs, val_auprcs, test_aurocs, test_auprcs = \
        print_all_evals(model, all_models, device, val_loader, test_loader, loss_func, print_detailed=False)

    # Find model with highest AUROC. Plot AUROC/AUPRC across all epochs.
    np_test_aurocs, test_auroc_idx = plot_auroc_auprc(val_losses, val_aurocs, val_auprcs, \
                                      test_aurocs, test_auprcs, all_models, best_epoch)

    ## AUROC / AUPRC - Model with Best Validation Loss
    best_model_val_loss = all_models[best_epoch]
    
    print(f'AUROC/AUPRC Plots - Best Model Based on Validation Loss')
    print(f'  Epoch with best Validation Loss:  {best_epoch:3}, {val_losses[best_epoch]:.4}')
    print(f'  Best Model Based on Validation Loss:')
    print(f'    {best_model_val_loss}')
    print()
    print(f'Generate Stats Based on Test Data')
    model.load_state_dict(torch.load(best_model_val_loss))
    model.train(False)
    
    best_model_val_test_predictions, best_model_val_test_labels, test_loss, \
        best_model_val_test_auroc, best_model_val_test_auprc, test_sensitivity, test_specificity, \
        best_model_val_test_threshold = eval_model(model, device, test_loader, loss_func, print_detailed=False)

    # y_test, y_pred
    display = RocCurveDisplay.from_predictions(
        best_model_val_test_labels,
        best_model_val_test_predictions,
        plot_chance_level=True
    )
    plt.show()

    print(f'best_model_val_test_auroc: {best_model_val_test_auroc}')

    best_model_val_test_predictions_binary = \
    (best_model_val_test_predictions > best_model_val_test_threshold).astype(int)

    # y_test, y_pred
    display = PrecisionRecallDisplay.from_predictions(
        best_model_val_test_labels, 
        best_model_val_test_predictions_binary,
        plot_chance_level=True
    )
    plt.show()

    print(f'best_model_val_test_auprc: {best_model_val_test_auprc}')
    print()

    ## AUROC / AUPRC - Model with Best AUROC
    # Find model with highest AUROC
    best_model_auroc = all_models[test_auroc_idx]

    print(f'AUROC/AUPRC Plots - Best Model Based on Model AUROC')
    print(f'  Epoch with best model Test AUROC: {test_auroc_idx:3}, {np.max(np_test_aurocs):.4}')
    print(f'  Best Model Based on Model AUROC:')
    print(f'    {best_model_auroc}')
    print()
    print(f'Generate Stats Based on Test Data')
    model.load_state_dict(torch.load(best_model_auroc))
    model.train(False)
    
    best_model_auroc_test_predictions, best_model_auroc_test_labels, test_loss, \
        best_model_auroc_test_auroc, best_model_auroc_test_auprc, test_sensitivity, test_specificity, \
        best_model_auroc_test_threshold = eval_model(model, device, test_loader, loss_func, print_detailed=False)

    # y_test, y_pred
    display = RocCurveDisplay.from_predictions(
        best_model_auroc_test_labels,
        best_model_auroc_test_predictions,
        plot_chance_level=True
    )
    plt.show()

    print(f'best_model_auroc_test_auroc: {best_model_auroc_test_auroc}')

    best_model_auroc_test_predictions_binary = \
        (best_model_auroc_test_predictions > best_model_auroc_test_threshold).astype(int)

    # y_test, y_pred
    display = PrecisionRecallDisplay.from_predictions(
        best_model_auroc_test_labels, 
        best_model_auroc_test_predictions_binary,
        plot_chance_level=True
    )
    plt.show()

    print(f"best_model_auroc_test_auprc: {best_model_auroc_test_auprc}")
In [97]:
print('Time to experiment!')
Time to experiment!
In [98]:
run_experiment(
    experimentNamePrefix=None, 
    useAbp=True, 
    useEeg=False, 
    useEcg=False,
    nResiduals=12, 
    skip_connection=False,
    batch_size=64,
    learning_rate=1e-4,
    weight_decay=0.0,
    balance_labels=False,
    #pos_weight=2.0,
    pos_weight=None,
    max_epochs=200,
    patience=50,
    device=device
)
Experiment Setup
  name:              ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES
  prediction_window: 003
  max_cases:         _ALL
  use_abp:           True
  use_eeg:           False
  use_ecg:           False
  n_residuals:       12
  skip_connection:   False
  batch_size:        64
  learning_rate:     0.0001
  weight_decay:      0.0
  balance_labels:    False
  max_epochs:        200
  patience:          50
  device:            mps

Model Architecture
HypotensionCNN(
  (abpResiduals): Sequential(
    (0): ResidualBlock(
      (bn1): BatchNorm1d(1, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(1, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (bn2): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (residualConv): Conv1d(1, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (downsample): MaxPool1d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    )
    (1): ResidualBlock(
      (bn1): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (bn2): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (residualConv): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
    )
    (2): ResidualBlock(
      (bn1): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (bn2): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (residualConv): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (downsample): MaxPool1d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    )
    (3): ResidualBlock(
      (bn1): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (bn2): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (residualConv): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
    )
    (4): ResidualBlock(
      (bn1): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (bn2): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (residualConv): Conv1d(2, 2, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (downsample): MaxPool1d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    )
    (5): ResidualBlock(
      (bn1): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(2, 4, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (bn2): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(4, 4, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
      (residualConv): Conv1d(2, 4, kernel_size=(15,), stride=(1,), padding=(7,), bias=False)
    )
    (6): ResidualBlock(
      (bn1): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (bn2): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (residualConv): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (downsample): MaxPool1d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    )
    (7): ResidualBlock(
      (bn1): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (bn2): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (residualConv): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
    )
    (8): ResidualBlock(
      (bn1): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (bn2): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (residualConv): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (downsample): MaxPool1d(kernel_size=2, stride=2, padding=1, dilation=1, ceil_mode=False)
    )
    (9): ResidualBlock(
      (bn1): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (bn2): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (residualConv): Conv1d(4, 4, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
    )
    (10): ResidualBlock(
      (bn1): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(4, 6, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (bn2): BatchNorm1d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(6, 6, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (residualConv): Conv1d(4, 6, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (downsample): MaxPool1d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    )
    (11): ResidualBlock(
      (bn1): BatchNorm1d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU()
      (dropout): Dropout(p=0.5, inplace=False)
      (conv1): Conv1d(6, 6, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (bn2): BatchNorm1d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (conv2): Conv1d(6, 6, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
      (residualConv): Conv1d(6, 6, kernel_size=(7,), stride=(1,), padding=(3,), bias=False)
    )
  )
  (abpFc): Linear(in_features=2814, out_features=32, bias=True)
  (fullLinear1): Linear(in_features=32, out_features=16, bias=True)
  (fullLinear2): Linear(in_features=16, out_features=1, bias=True)
  (sigmoid): Sigmoid()
)

Training Loop
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:49<00:00,  3.74it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.87it/s]
[2024-05-02 02:59:45.104652] Completed epoch 0 with training loss 0.47095051, validation loss 0.61229235
Validation loss improved to 0.61229235. Model saved.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:45<00:00,  4.08it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  5.10it/s]
[2024-05-02 03:00:36.499070] Completed epoch 1 with training loss 0.43696883, validation loss 0.58043462
Validation loss improved to 0.58043462. Model saved.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.98it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.84it/s]
[2024-05-02 03:01:29.482466] Completed epoch 2 with training loss 0.43396759, validation loss 0.62232143
No improvement in validation loss. 1 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.93it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.86it/s]
[2024-05-02 03:02:22.906298] Completed epoch 3 with training loss 0.43050513, validation loss 0.55514252
Validation loss improved to 0.55514252. Model saved.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.93it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.86it/s]
[2024-05-02 03:03:16.384366] Completed epoch 4 with training loss 0.42715833, validation loss 0.68393040
No improvement in validation loss. 1 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.85it/s]
[2024-05-02 03:04:09.982359] Completed epoch 5 with training loss 0.42504692, validation loss 0.62195766
No improvement in validation loss. 2 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.93it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.77it/s]
[2024-05-02 03:05:03.609489] Completed epoch 6 with training loss 0.42442331, validation loss 0.48527575
Validation loss improved to 0.48527575. Model saved.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.85it/s]
[2024-05-02 03:05:57.232774] Completed epoch 7 with training loss 0.42127559, validation loss 0.56069189
No improvement in validation loss. 1 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.93it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.85it/s]
[2024-05-02 03:06:50.740734] Completed epoch 8 with training loss 0.42093799, validation loss 0.63055253
No improvement in validation loss. 2 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:07:44.216561] Completed epoch 9 with training loss 0.41865537, validation loss 0.52063578
No improvement in validation loss. 3 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.95it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.87it/s]
[2024-05-02 03:08:37.363564] Completed epoch 10 with training loss 0.41986549, validation loss 0.51428044
No improvement in validation loss. 4 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.95it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.89it/s]
[2024-05-02 03:09:30.556345] Completed epoch 11 with training loss 0.41403154, validation loss 0.51539260
No improvement in validation loss. 5 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.94it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:10:23.767211] Completed epoch 12 with training loss 0.41340354, validation loss 0.53828967
No improvement in validation loss. 6 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.93it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:11:17.157333] Completed epoch 13 with training loss 0.41379434, validation loss 0.50058013
No improvement in validation loss. 7 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.95it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:12:10.308141] Completed epoch 14 with training loss 0.40928683, validation loss 0.53610170
No improvement in validation loss. 8 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.94it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.83it/s]
[2024-05-02 03:13:03.702263] Completed epoch 15 with training loss 0.41129714, validation loss 0.50965858
No improvement in validation loss. 9 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.87it/s]
[2024-05-02 03:13:57.216093] Completed epoch 16 with training loss 0.41109890, validation loss 0.50798094
No improvement in validation loss. 10 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.94it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:14:50.472581] Completed epoch 17 with training loss 0.40682951, validation loss 0.55750942
No improvement in validation loss. 11 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:15:43.931166] Completed epoch 18 with training loss 0.40591910, validation loss 0.52356601
No improvement in validation loss. 12 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.93it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 03:16:37.287460] Completed epoch 19 with training loss 0.40441728, validation loss 0.51499552
No improvement in validation loss. 13 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.88it/s]
[2024-05-02 03:17:30.791407] Completed epoch 20 with training loss 0.40161708, validation loss 0.58782870
No improvement in validation loss. 14 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 03:18:24.216645] Completed epoch 21 with training loss 0.40194839, validation loss 0.52258706
No improvement in validation loss. 15 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:19:17.749379] Completed epoch 22 with training loss 0.40075284, validation loss 0.53204823
No improvement in validation loss. 16 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:20:11.206824] Completed epoch 23 with training loss 0.39961624, validation loss 0.52817714
No improvement in validation loss. 17 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.93it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.82it/s]
[2024-05-02 03:21:04.682107] Completed epoch 24 with training loss 0.39566550, validation loss 0.48220193
Validation loss improved to 0.48220193. Model saved.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:21:58.215015] Completed epoch 25 with training loss 0.39820033, validation loss 0.52757311
No improvement in validation loss. 1 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 03:22:51.743224] Completed epoch 26 with training loss 0.39712259, validation loss 0.54991436
No improvement in validation loss. 2 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:23:45.317802] Completed epoch 27 with training loss 0.39330235, validation loss 0.59737325
No improvement in validation loss. 3 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.89it/s]
[2024-05-02 03:24:38.835339] Completed epoch 28 with training loss 0.39381751, validation loss 0.55142957
No improvement in validation loss. 4 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.93it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.89it/s]
[2024-05-02 03:25:32.274791] Completed epoch 29 with training loss 0.39497167, validation loss 0.49872923
No improvement in validation loss. 5 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.93it/s]
[2024-05-02 03:26:25.731229] Completed epoch 30 with training loss 0.39178732, validation loss 0.51278424
No improvement in validation loss. 6 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 03:27:19.296881] Completed epoch 31 with training loss 0.38930377, validation loss 0.55706477
No improvement in validation loss. 7 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.89it/s]
[2024-05-02 03:28:12.814078] Completed epoch 32 with training loss 0.39003900, validation loss 0.57714516
No improvement in validation loss. 8 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.86it/s]
[2024-05-02 03:29:06.490885] Completed epoch 33 with training loss 0.38764787, validation loss 0.54014730
No improvement in validation loss. 9 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 03:30:00.157219] Completed epoch 34 with training loss 0.38762611, validation loss 0.53876853
No improvement in validation loss. 10 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:30:53.893743] Completed epoch 35 with training loss 0.38292289, validation loss 0.56879377
No improvement in validation loss. 11 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:48<00:00,  3.83it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:31:48.465584] Completed epoch 36 with training loss 0.38319844, validation loss 0.53786266
No improvement in validation loss. 12 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:32:42.090527] Completed epoch 37 with training loss 0.38270748, validation loss 0.55635995
No improvement in validation loss. 13 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.88it/s]
[2024-05-02 03:33:35.876259] Completed epoch 38 with training loss 0.38069484, validation loss 0.54526842
No improvement in validation loss. 14 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.88it/s]
[2024-05-02 03:34:29.673488] Completed epoch 39 with training loss 0.37690097, validation loss 0.55808699
No improvement in validation loss. 15 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.93it/s]
[2024-05-02 03:35:23.325516] Completed epoch 40 with training loss 0.37852138, validation loss 0.52281606
No improvement in validation loss. 16 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:36:16.811171] Completed epoch 41 with training loss 0.37706375, validation loss 0.61506164
No improvement in validation loss. 17 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.93it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:37:10.176090] Completed epoch 42 with training loss 0.37705389, validation loss 0.53971589
No improvement in validation loss. 18 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.94it/s]
[2024-05-02 03:38:03.582878] Completed epoch 43 with training loss 0.37497702, validation loss 0.55682707
No improvement in validation loss. 19 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 03:38:57.116283] Completed epoch 44 with training loss 0.37428856, validation loss 0.52316660
No improvement in validation loss. 20 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:39:50.897809] Completed epoch 45 with training loss 0.37099221, validation loss 0.57345325
No improvement in validation loss. 21 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.89it/s]
[2024-05-02 03:40:44.658785] Completed epoch 46 with training loss 0.36929455, validation loss 0.53808379
No improvement in validation loss. 22 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.89it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:41:38.501446] Completed epoch 47 with training loss 0.36767173, validation loss 0.59356380
No improvement in validation loss. 23 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.89it/s]
[2024-05-02 03:42:32.125150] Completed epoch 48 with training loss 0.36818969, validation loss 0.65569478
No improvement in validation loss. 24 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:43:25.851065] Completed epoch 49 with training loss 0.36562589, validation loss 0.60468376
No improvement in validation loss. 25 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:44:19.586390] Completed epoch 50 with training loss 0.36544737, validation loss 0.54185951
No improvement in validation loss. 26 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.89it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:45:13.480483] Completed epoch 51 with training loss 0.36287862, validation loss 0.58746821
No improvement in validation loss. 27 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:46:07.170812] Completed epoch 52 with training loss 0.36183456, validation loss 0.60116875
No improvement in validation loss. 28 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.86it/s]
[2024-05-02 03:47:01.009737] Completed epoch 53 with training loss 0.36141935, validation loss 0.61058605
No improvement in validation loss. 29 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.89it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.83it/s]
[2024-05-02 03:47:54.928439] Completed epoch 54 with training loss 0.35817906, validation loss 0.63989830
No improvement in validation loss. 30 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:48:48.564753] Completed epoch 55 with training loss 0.36123911, validation loss 0.60557353
No improvement in validation loss. 31 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:46<00:00,  3.92it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:49:42.039348] Completed epoch 56 with training loss 0.35713097, validation loss 0.61435843
No improvement in validation loss. 32 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 03:50:35.639553] Completed epoch 57 with training loss 0.35635632, validation loss 0.61872959
No improvement in validation loss. 33 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.89it/s]
[2024-05-02 03:51:29.378371] Completed epoch 58 with training loss 0.35855842, validation loss 0.63077319
No improvement in validation loss. 34 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:52:23.048633] Completed epoch 59 with training loss 0.35144931, validation loss 0.59190547
No improvement in validation loss. 35 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.88it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:53:16.989988] Completed epoch 60 with training loss 0.35552490, validation loss 0.60619813
No improvement in validation loss. 36 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.89it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 03:54:10.866199] Completed epoch 61 with training loss 0.35634133, validation loss 0.56168914
No improvement in validation loss. 37 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.85it/s]
[2024-05-02 03:55:04.616634] Completed epoch 62 with training loss 0.35280845, validation loss 0.64174330
No improvement in validation loss. 38 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.89it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 03:55:58.411747] Completed epoch 63 with training loss 0.35206974, validation loss 0.59210002
No improvement in validation loss. 39 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.93it/s]
[2024-05-02 03:56:52.175732] Completed epoch 64 with training loss 0.35010892, validation loss 0.60631543
No improvement in validation loss. 40 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.93it/s]
[2024-05-02 03:57:45.845198] Completed epoch 65 with training loss 0.34702799, validation loss 0.66165757
No improvement in validation loss. 41 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 03:58:39.529248] Completed epoch 66 with training loss 0.34570220, validation loss 0.64781594
No improvement in validation loss. 42 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.89it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 03:59:33.390053] Completed epoch 67 with training loss 0.34220779, validation loss 0.57615894
No improvement in validation loss. 43 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.91it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 04:00:27.072455] Completed epoch 68 with training loss 0.34439984, validation loss 0.59308290
No improvement in validation loss. 44 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.88it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 04:01:21.049932] Completed epoch 69 with training loss 0.34374011, validation loss 0.63423276
No improvement in validation loss. 45 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.89it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 04:02:14.870636] Completed epoch 70 with training loss 0.34525377, validation loss 0.64052284
No improvement in validation loss. 46 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.88it/s]
[2024-05-02 04:03:08.640620] Completed epoch 71 with training loss 0.34609577, validation loss 0.61197329
No improvement in validation loss. 47 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
[2024-05-02 04:04:02.419419] Completed epoch 72 with training loss 0.34008214, validation loss 0.60943377
No improvement in validation loss. 48 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.90it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.92it/s]
[2024-05-02 04:04:56.161013] Completed epoch 73 with training loss 0.33975908, validation loss 0.61680305
No improvement in validation loss. 49 epochs without improvement.
100%|█████████████████████████████████████████████████████████████████████████████████████| 184/184 [00:47<00:00,  3.89it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.91it/s]
[2024-05-02 04:05:49.990743] Completed epoch 74 with training loss 0.34147960, validation loss 0.61249352
No improvement in validation loss. 50 epochs without improvement.
Early stopping due to no improvement in validation loss.

Plot Validation and Loss Values from Training
  Epoch with best Validation Loss:   24, 0.4822
Generate AUROC/AUPRC for Each Intermediate Model

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0000.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:05<00:00,  5.50it/s]
Loss: 0.6097345985472202
AUROC: 0.8434897822708655
AUPRC: 0.6958378595439778
Sensitivity: 0.7529610829103215
Specificity: 0.7728551336146273
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.77it/s]
Loss: 0.5698916980976699
AUROC: 0.8320580198616765
AUPRC: 0.6762607164287759
Sensitivity: 0.776500638569604
Specificity: 0.7353613906678865
Threshold: 0.11

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0001.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.94it/s]
Loss: 0.5771821551024914
AUROC: 0.8443185523118699
AUPRC: 0.7017892863068145
Sensitivity: 0.766497461928934
Specificity: 0.7658227848101266
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.97it/s]
Loss: 0.5465086802680005
AUROC: 0.8349491831800884
AUPRC: 0.683286292186806
Sensitivity: 0.7413793103448276
Specificity: 0.7779048490393413
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0002.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.624913452193141
AUROC: 0.8439151739286674
AUPRC: 0.7039187396823574
Sensitivity: 0.7614213197969543
Specificity: 0.7693389592123769
Threshold: 0.09

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.89it/s]
Loss: 0.5849494398922048
AUROC: 0.8356757532842809
AUPRC: 0.6858254031163499
Sensitivity: 0.7407407407407407
Specificity: 0.7781335773101555
Threshold: 0.09

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0003.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.5577499335631728
AUROC: 0.8445220263635737
AUPRC: 0.703566209252847
Sensitivity: 0.7563451776649747
Specificity: 0.7721518987341772
Threshold: 0.13

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.96it/s]
Loss: 0.5266809679808155
AUROC: 0.836454904600155
AUPRC: 0.6860131106417616
Sensitivity: 0.7662835249042146
Specificity: 0.7548032936870998
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0004.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.6932881399989128
AUROC: 0.8446374473168794
AUPRC: 0.7051974578767596
Sensitivity: 0.754653130287648
Specificity: 0.7714486638537271
Threshold: 0.06

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.94it/s]
Loss: 0.6485231262381359
AUROC: 0.8365717517372248
AUPRC: 0.686771546895351
Sensitivity: 0.7401021711366539
Specificity: 0.7797346752058555
Threshold: 0.06

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0005.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.95it/s]
Loss: 0.6199646601453424
AUROC: 0.8441864726642726
AUPRC: 0.7031626709178587
Sensitivity: 0.7715736040609137
Specificity: 0.7538677918424754
Threshold: 0.08

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.96it/s]
Loss: 0.5856725328391598
AUROC: 0.836007014917874
AUPRC: 0.6845272675448782
Sensitivity: 0.7573435504469987
Specificity: 0.7616651418115279
Threshold: 0.08

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0006.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.4839087165892124
AUROC: 0.8416353126241966
AUPRC: 0.6959814259485282
Sensitivity: 0.7749576988155669
Specificity: 0.7559774964838256
Threshold: 0.22

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.92it/s]
Loss: 0.4659055107703773
AUROC: 0.8334367430496402
AUPRC: 0.677934985398352
Sensitivity: 0.7650063856960408
Specificity: 0.7490850869167429
Threshold: 0.21

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0007.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.89it/s]
Loss: 0.5606617899611592
AUROC: 0.8440067967472709
AUPRC: 0.6969732363858123
Sensitivity: 0.7749576988155669
Specificity: 0.7566807313642757
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.5310483831231312
AUROC: 0.8360306764631306
AUPRC: 0.6818760094170057
Sensitivity: 0.7535121328224776
Specificity: 0.7708142726440989
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0008.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.6304401233792305
AUROC: 0.8430001356493678
AUPRC: 0.6978592607338601
Sensitivity: 0.7783417935702199
Specificity: 0.749648382559775
Threshold: 0.08

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.5929592791744458
AUROC: 0.8357809887371045
AUPRC: 0.6812358713178048
Sensitivity: 0.7618135376756067
Specificity: 0.760064043915828
Threshold: 0.08

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0009.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.94it/s]
Loss: 0.5183204533532262
AUROC: 0.8413402157538892
AUPRC: 0.6891831967719046
Sensitivity: 0.766497461928934
Specificity: 0.7566807313642757
Threshold: 0.17

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.97it/s]
Loss: 0.49298066461599
AUROC: 0.8336945370458005
AUPRC: 0.6714642487619407
Sensitivity: 0.768837803320562
Specificity: 0.7502287282708143
Threshold: 0.16

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0010.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.5146410185843706
AUROC: 0.8389949095789871
AUPRC: 0.6880579796255863
Sensitivity: 0.7563451776649747
Specificity: 0.7665260196905767
Threshold: 0.18

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.94it/s]
Loss: 0.48881879769345765
AUROC: 0.8324435423845463
AUPRC: 0.6709274957031406
Sensitivity: 0.7567049808429118
Specificity: 0.7552607502287283
Threshold: 0.17

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0011.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.5241169976070523
AUROC: 0.8395125190087601
AUPRC: 0.6861002753485496
Sensitivity: 0.7715736040609137
Specificity: 0.7580872011251758
Threshold: 0.17

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.95it/s]
Loss: 0.4939338090599224
AUROC: 0.8325742651191432
AUPRC: 0.6702948620610406
Sensitivity: 0.7675606641123882
Specificity: 0.7472552607502287
Threshold: 0.16

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0012.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.5452408324927092
AUROC: 0.840096763215699
AUPRC: 0.6857631906224092
Sensitivity: 0.766497461928934
Specificity: 0.759493670886076
Threshold: 0.14

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.90it/s]
Loss: 0.5136698476409399
AUROC: 0.8332863023606626
AUPRC: 0.6721428470558165
Sensitivity: 0.7464878671775224
Specificity: 0.7719579139981702
Threshold: 0.14

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0013.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
Loss: 0.5001151897013187
AUROC: 0.8380501236313098
AUPRC: 0.6773977193802111
Sensitivity: 0.7597292724196277
Specificity: 0.7672292545710268
Threshold: 0.2

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.4793920172478563
AUROC: 0.8312340284569518
AUPRC: 0.6650486835143032
Sensitivity: 0.7586206896551724
Specificity: 0.7548032936870998
Threshold: 0.19

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0014.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.68it/s]
Loss: 0.5311963632702827
AUROC: 0.8393161843974669
AUPRC: 0.6766754468154347
Sensitivity: 0.7614213197969543
Specificity: 0.7672292545710268
Threshold: 0.15

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.65it/s]
Loss: 0.5067254114215092
AUROC: 0.8328973474531413
AUPRC: 0.6674025188029576
Sensitivity: 0.7598978288633461
Specificity: 0.7637236962488564
Threshold: 0.14

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0015.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.80it/s]
Loss: 0.5091120218858123
AUROC: 0.8387462190713492
AUPRC: 0.672434682489459
Sensitivity: 0.7732656514382402
Specificity: 0.7630098452883263
Threshold: 0.17

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.75it/s]
Loss: 0.4865872021964801
AUROC: 0.8318115454319195
AUPRC: 0.6633881724446768
Sensitivity: 0.7637292464878672
Specificity: 0.7552607502287283
Threshold: 0.16

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0016.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.72it/s]
Loss: 0.5099533442407846
AUROC: 0.8380620226986608
AUPRC: 0.6695619041408551
Sensitivity: 0.7614213197969543
Specificity: 0.770745428973277
Threshold: 0.18

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.79it/s]
Loss: 0.48438095405537596
AUROC: 0.8312210292129528
AUPRC: 0.66326300522572
Sensitivity: 0.7669220945083014
Specificity: 0.7522872827081427
Threshold: 0.16

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0017.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.84it/s]
Loss: 0.5611289702355862
AUROC: 0.8369363709272467
AUPRC: 0.666472739505355
Sensitivity: 0.7614213197969543
Specificity: 0.7679324894514767
Threshold: 0.13

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.84it/s]
Loss: 0.5289972402075286
AUROC: 0.8311607068784405
AUPRC: 0.6590008832486736
Sensitivity: 0.7554278416347382
Specificity: 0.7586916742909423
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0018.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.86it/s]
Loss: 0.5187493897974491
AUROC: 0.8353323766483183
AUPRC: 0.659931927888682
Sensitivity: 0.7631133671742809
Specificity: 0.7644163150492265
Threshold: 0.16

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.84it/s]
Loss: 0.496190276838118
AUROC: 0.8300965215775765
AUPRC: 0.6564854796146771
Sensitivity: 0.7541507024265645
Specificity: 0.7612076852698993
Threshold: 0.15

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0019.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.82it/s]
Loss: 0.5178426001220942
AUROC: 0.8326943534165792
AUPRC: 0.6502063227055326
Sensitivity: 0.7631133671742809
Specificity: 0.7538677918424754
Threshold: 0.17

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.84it/s]
Loss: 0.48704761843527516
AUROC: 0.8275102562574562
AUPRC: 0.6475242098808809
Sensitivity: 0.7650063856960408
Specificity: 0.7470265324794144
Threshold: 0.16

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0020.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.88it/s]
Loss: 0.5902411267161369
AUROC: 0.8360665491038812
AUPRC: 0.6663012402173
Sensitivity: 0.7614213197969543
Specificity: 0.7623066104078763
Threshold: 0.1

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.86it/s]
Loss: 0.5577557002023984
AUROC: 0.8308196592971177
AUPRC: 0.6600306431099726
Sensitivity: 0.7630906768837803
Specificity: 0.7504574565416285
Threshold: 0.09

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0021.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.5249563902616501
AUROC: 0.83178407476422
AUPRC: 0.6538039343996608
Sensitivity: 0.751269035532995
Specificity: 0.7552742616033755
Threshold: 0.15

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.67it/s]
Loss: 0.4973587792727255
AUROC: 0.827064192311692
AUPRC: 0.6488825145991081
Sensitivity: 0.756066411238825
Specificity: 0.7502287282708143
Threshold: 0.14

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0022.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.85it/s]
Loss: 0.5292598688974977
AUROC: 0.8323397612095162
AUPRC: 0.6529581357009536
Sensitivity: 0.7478849407783418
Specificity: 0.7559774964838256
Threshold: 0.15

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:19<00:00,  4.85it/s]
Loss: 0.49956161536837135
AUROC: 0.8268319586267656
AUPRC: 0.6482777923966707
Sensitivity: 0.7515964240102171
Specificity: 0.7522872827081427
Threshold: 0.14

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0023.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
Loss: 0.533031995408237
AUROC: 0.8296339132938761
AUPRC: 0.6450411515418035
Sensitivity: 0.751269035532995
Specificity: 0.7538677918424754
Threshold: 0.15

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.95it/s]
Loss: 0.5010369793381743
AUROC: 0.8244069423558018
AUPRC: 0.6418418318529125
Sensitivity: 0.7567049808429118
Specificity: 0.7451967063129002
Threshold: 0.14

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0024.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.95it/s]
Loss: 0.48274488002061844
AUROC: 0.8262664772335144
AUPRC: 0.6390023181372644
Sensitivity: 0.7445008460236887
Specificity: 0.7559774964838256
Threshold: 0.22

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.46309909272578453
AUROC: 0.8211523114116418
AUPRC: 0.6350720866597654
Sensitivity: 0.7413793103448276
Specificity: 0.7564043915827996
Threshold: 0.21

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0025.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
Loss: 0.5303412154316902
AUROC: 0.8271017917615616
AUPRC: 0.6388681350792631
Sensitivity: 0.7597292724196277
Specificity: 0.749648382559775
Threshold: 0.15

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.95it/s]
Loss: 0.49842497129594127
AUROC: 0.8227114173674573
AUPRC: 0.6366033541142847
Sensitivity: 0.7547892720306514
Specificity: 0.7406221408966148
Threshold: 0.14

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0026.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.5497674942016602
AUROC: 0.8289140197191346
AUPRC: 0.643496611012102
Sensitivity: 0.7597292724196277
Specificity: 0.7482419127988749
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.90it/s]
Loss: 0.5221350330819365
AUROC: 0.8239269927402874
AUPRC: 0.6410239648911229
Sensitivity: 0.7458492975734355
Specificity: 0.757548032936871
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0027.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.90it/s]
Loss: 0.599209887906909
AUROC: 0.8281834169837768
AUPRC: 0.6406191580588525
Sensitivity: 0.7495769881556683
Specificity: 0.7573839662447257
Threshold: 0.1

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.91it/s]
Loss: 0.5611174096984248
AUROC: 0.8224217094969848
AUPRC: 0.6376131020034153
Sensitivity: 0.7535121328224776
Specificity: 0.7433668801463861
Threshold: 0.09

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0028.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.93it/s]
Loss: 0.5538912760093808
AUROC: 0.8253883260630032
AUPRC: 0.6385479718310824
Sensitivity: 0.7631133671742809
Specificity: 0.740506329113924
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.91it/s]
Loss: 0.5222505435187329
AUROC: 0.8213624901994464
AUPRC: 0.6386152427575726
Sensitivity: 0.743933588761175
Specificity: 0.7527447392497713
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0029.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.4972596578299999
AUROC: 0.8182357966782563
AUPRC: 0.6190529452734552
Sensitivity: 0.7411167512690355
Specificity: 0.7566807313642757
Threshold: 0.21

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.92it/s]
Loss: 0.47150564017475294
AUROC: 0.8136518936831268
AUPRC: 0.6199701346632377
Sensitivity: 0.7490421455938697
Specificity: 0.7339890210430009
Threshold: 0.19

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0030.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.95it/s]
Loss: 0.5151585154235363
AUROC: 0.8124052536762169
AUPRC: 0.6112815698344429
Sensitivity: 0.7478849407783418
Specificity: 0.7334739803094233
Threshold: 0.18

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.91it/s]
Loss: 0.4835433804540224
AUROC: 0.8104870889755894
AUPRC: 0.6140686428132276
Sensitivity: 0.743933588761175
Specificity: 0.7257548032936871
Threshold: 0.17

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0031.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.5510827861726284
AUROC: 0.8221987810595405
AUPRC: 0.6334073015321134
Sensitivity: 0.7445008460236887
Specificity: 0.7580872011251758
Threshold: 0.13

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.95it/s]
Loss: 0.5183616075464474
AUROC: 0.8190381815547446
AUPRC: 0.6341995446539596
Sensitivity: 0.7394636015325671
Specificity: 0.7506861848124429
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0032.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.5747008095495403
AUROC: 0.8148600312707489
AUPRC: 0.6181002907320512
Sensitivity: 0.7495769881556683
Specificity: 0.7348804500703235
Threshold: 0.11

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.96it/s]
Loss: 0.5427401395895148
AUROC: 0.812500219088382
AUPRC: 0.6185353745332086
Sensitivity: 0.7330779054916986
Specificity: 0.7451967063129002
Threshold: 0.11

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0033.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.94it/s]
Loss: 0.5334354490041733
AUROC: 0.8105686326305743
AUPRC: 0.6077691593552714
Sensitivity: 0.751269035532995
Specificity: 0.729254571026723
Threshold: 0.15

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.5027886646729643
AUROC: 0.8077476078469863
AUPRC: 0.6075319690810637
Sensitivity: 0.7241379310344828
Specificity: 0.7435956084172004
Threshold: 0.15

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0034.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.5417610257863998
AUROC: 0.8129430915204867
AUPRC: 0.6111245377874746
Sensitivity: 0.7326565143824028
Specificity: 0.7524613220815752
Threshold: 0.15

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.5091843725212158
AUROC: 0.8092186402732353
AUPRC: 0.6124575042712372
Sensitivity: 0.7324393358876118
Specificity: 0.739935956084172
Threshold: 0.14

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0035.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.99it/s]
Loss: 0.5630659777671099
AUROC: 0.8115282924124406
AUPRC: 0.6144475898870979
Sensitivity: 0.7377326565143824
Specificity: 0.7376933895921237
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.98it/s]
Loss: 0.5306326155700991
AUROC: 0.8095831303114325
AUPRC: 0.6150872632932314
Sensitivity: 0.7254150702426565
Specificity: 0.7493138151875571
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0036.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.99it/s]
Loss: 0.5417152615264058
AUROC: 0.8151717868353479
AUPRC: 0.6211123223972963
Sensitivity: 0.7411167512690355
Specificity: 0.7468354430379747
Threshold: 0.14

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.99it/s]
Loss: 0.5095770474403135
AUROC: 0.8127461092824533
AUPRC: 0.6212268664606534
Sensitivity: 0.7362707535121328
Specificity: 0.742451967063129
Threshold: 0.13

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0037.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.5539900083094835
AUROC: 0.8126944010128486
AUPRC: 0.6149432394167437
Sensitivity: 0.7360406091370558
Specificity: 0.7454289732770746
Threshold: 0.13

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.96it/s]
Loss: 0.5219316062747791
AUROC: 0.8097493453639146
AUPRC: 0.6154101147928074
Sensitivity: 0.7432950191570882
Specificity: 0.7369624885635865
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0038.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  5.00it/s]
Loss: 0.5403719320893288
AUROC: 0.8131798829607736
AUPRC: 0.617328969050527
Sensitivity: 0.7309644670050761
Specificity: 0.7454289732770746
Threshold: 0.14

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.96it/s]
Loss: 0.5092891198332592
AUROC: 0.8098290935349648
AUPRC: 0.617988082837601
Sensitivity: 0.7381864623243933
Specificity: 0.7422232387923148
Threshold: 0.13

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0039.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.95it/s]
Loss: 0.558999439701438
AUROC: 0.8088510022584431
AUPRC: 0.61239712458226
Sensitivity: 0.7411167512690355
Specificity: 0.729957805907173
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.99it/s]
Loss: 0.5270173940607297
AUROC: 0.8066400430464852
AUPRC: 0.6134332488850192
Sensitivity: 0.7260536398467433
Specificity: 0.7463403476669717
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0040.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.517260649241507
AUROC: 0.8088438628180322
AUPRC: 0.6105013477590177
Sensitivity: 0.7309644670050761
Specificity: 0.7390998593530239
Threshold: 0.17

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.98it/s]
Loss: 0.48834859539744674
AUROC: 0.8056915364113207
AUPRC: 0.6115310732352306
Sensitivity: 0.731162196679438
Specificity: 0.7387923147301007
Threshold: 0.16

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0041.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.6098237130790949
AUROC: 0.8108321969724013
AUPRC: 0.6157927911991042
Sensitivity: 0.7360406091370558
Specificity: 0.7447257383966245
Threshold: 0.09

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.94it/s]
Loss: 0.575101426371964
AUROC: 0.8067022641469751
AUPRC: 0.6136420263904503
Sensitivity: 0.7349936143039592
Specificity: 0.729871912168344
Threshold: 0.08

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0042.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.93it/s]
Loss: 0.5430210176855326
AUROC: 0.7990461707611357
AUPRC: 0.5972474240647593
Sensitivity: 0.727580372250423
Specificity: 0.7285513361462729
Threshold: 0.15

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.97it/s]
Loss: 0.5078299471768
AUROC: 0.7975960016078167
AUPRC: 0.5970325154157392
Sensitivity: 0.7330779054916986
Specificity: 0.7227813357731016
Threshold: 0.14

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0043.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.5564766572788358
AUROC: 0.8069983174718766
AUPRC: 0.6084037900825818
Sensitivity: 0.7309644670050761
Specificity: 0.7390998593530239
Threshold: 0.13

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.92it/s]
Loss: 0.519142208400593
AUROC: 0.8050840773574786
AUPRC: 0.6107805840682811
Sensitivity: 0.7343550446998723
Specificity: 0.7371912168344007
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0044.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.5263814274221659
AUROC: 0.8008369803974764
AUPRC: 0.6038520857305871
Sensitivity: 0.7360406091370558
Specificity: 0.7362869198312236
Threshold: 0.17

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.94it/s]
Loss: 0.48953313612809746
AUROC: 0.8023583257674811
AUPRC: 0.6078763917577166
Sensitivity: 0.7394636015325671
Specificity: 0.722323879231473
Threshold: 0.16

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0045.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.5696249436587095
AUROC: 0.7955311862656205
AUPRC: 0.5902182405856551
Sensitivity: 0.7140439932318104
Specificity: 0.7362869198312236
Threshold: 0.13

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.95it/s]
Loss: 0.5322273596320101
AUROC: 0.7958913479368885
AUPRC: 0.5962927810646433
Sensitivity: 0.7209450830140486
Specificity: 0.7278133577310155
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0046.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.5405772598460317
AUROC: 0.7955692632811441
AUPRC: 0.5880126321651067
Sensitivity: 0.7225042301184433
Specificity: 0.7341772151898734
Threshold: 0.16

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.98it/s]
Loss: 0.5027217820126523
AUROC: 0.7971092602524599
AUPRC: 0.5956844081701933
Sensitivity: 0.7273307790549169
Specificity: 0.7333028362305581
Threshold: 0.15

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0047.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.99it/s]
Loss: 0.5906612412072718
AUROC: 0.8076789441243595
AUPRC: 0.61016574471547
Sensitivity: 0.7292724196277496
Specificity: 0.7538677918424754
Threshold: 0.1

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.95it/s]
Loss: 0.5543645474539008
AUROC: 0.808596940474563
AUPRC: 0.6180756208223442
Sensitivity: 0.7343550446998723
Specificity: 0.739935956084172
Threshold: 0.09

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0048.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.88it/s]
Loss: 0.6558127561584115
AUROC: 0.8028943291424818
AUPRC: 0.6013210701706377
Sensitivity: 0.7495769881556683
Specificity: 0.7271448663853727
Threshold: 0.07

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.96it/s]
Loss: 0.604617083425163
AUROC: 0.8051831053061453
AUPRC: 0.612807710554399
Sensitivity: 0.722860791826309
Specificity: 0.7442817932296432
Threshold: 0.07

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0049.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.5899367621168494
AUROC: 0.7793663032691498
AUPRC: 0.5723925750643883
Sensitivity: 0.7157360406091371
Specificity: 0.7215189873417721
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.94it/s]
Loss: 0.5404496048727343
AUROC: 0.7863603460544811
AUPRC: 0.5817133852289831
Sensitivity: 0.7088122605363985
Specificity: 0.7262122598353157
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0050.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.5450304578989744
AUROC: 0.7878872253992732
AUPRC: 0.581399749574193
Sensitivity: 0.7106598984771574
Specificity: 0.7306610407876231
Threshold: 0.17

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.97it/s]
Loss: 0.49820134027670787
AUROC: 0.7939232770013285
AUPRC: 0.5932727748123447
Sensitivity: 0.7215836526181354
Specificity: 0.7296431838975297
Threshold: 0.16

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0051.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.99it/s]
Loss: 0.5834860829636455
AUROC: 0.791235622951873
AUPRC: 0.586829865700232
Sensitivity: 0.7208121827411168
Specificity: 0.7334739803094233
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.5363494144972935
AUROC: 0.7965583260011755
AUPRC: 0.5991765095740761
Sensitivity: 0.7241379310344828
Specificity: 0.7271271729185728
Threshold: 0.11

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0052.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.6050967881456017
AUROC: 0.786928755524142
AUPRC: 0.5788209525505056
Sensitivity: 0.7174280879864636
Specificity: 0.7222222222222222
Threshold: 0.11

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.5510191992726378
AUROC: 0.7922939897338106
AUPRC: 0.5896610179354345
Sensitivity: 0.7292464878671775
Specificity: 0.7186642268984447
Threshold: 0.1

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0053.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.6123037291690707
AUROC: 0.7796019048027016
AUPRC: 0.5699214261648701
Sensitivity: 0.6971235194585449
Specificity: 0.7264416315049227
Threshold: 0.11

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.94it/s]
Loss: 0.5584052717813881
AUROC: 0.7876386537340256
AUPRC: 0.5824008892764747
Sensitivity: 0.7177522349936143
Specificity: 0.7204940530649588
Threshold: 0.1

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0054.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.95it/s]
Loss: 0.6436314526945353
AUROC: 0.7852218343126266
AUPRC: 0.5788671645950514
Sensitivity: 0.7343485617597293
Specificity: 0.7137834036568214
Threshold: 0.08

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.97it/s]
Loss: 0.5851129953579236
AUROC: 0.7929014487876525
AUPRC: 0.5922364306513146
Sensitivity: 0.719029374201788
Specificity: 0.7278133577310155
Threshold: 0.08

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0055.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.603963965550065
AUROC: 0.7876349651714298
AUPRC: 0.5821839744255215
Sensitivity: 0.7123519458544839
Specificity: 0.7334739803094233
Threshold: 0.11

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.5504261405878169
AUROC: 0.795701909515914
AUPRC: 0.5990702620868937
Sensitivity: 0.7273307790549169
Specificity: 0.7234675205855444
Threshold: 0.1

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0056.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.95it/s]
Loss: 0.6201467616483569
AUROC: 0.7802801516417143
AUPRC: 0.5684900567591553
Sensitivity: 0.7258883248730964
Specificity: 0.7137834036568214
Threshold: 0.1

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.97it/s]
Loss: 0.5605922049732619
AUROC: 0.7888864350990105
AUPRC: 0.5832816798677978
Sensitivity: 0.7164750957854407
Specificity: 0.7275846294602013
Threshold: 0.1

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0057.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.93it/s]
Loss: 0.6236360175535083
AUROC: 0.7846268809450715
AUPRC: 0.5775818304208236
Sensitivity: 0.7326565143824028
Specificity: 0.7067510548523207
Threshold: 0.09

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.90it/s]
Loss: 0.571203847405731
AUROC: 0.7917465608966383
AUPRC: 0.5910632953108911
Sensitivity: 0.7196679438058748
Specificity: 0.7227813357731016
Threshold: 0.09

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0058.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.6336376518011093
AUROC: 0.7840473963650729
AUPRC: 0.5786271857859527
Sensitivity: 0.7157360406091371
Specificity: 0.7172995780590717
Threshold: 0.09

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.94it/s]
Loss: 0.577198594648351
AUROC: 0.7912996205973458
AUPRC: 0.5911714352518007
Sensitivity: 0.7158365261813537
Specificity: 0.7301006404391582
Threshold: 0.09

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0059.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.5904513793066144
AUROC: 0.7727706502364344
AUPRC: 0.5598841476907221
Sensitivity: 0.7157360406091371
Specificity: 0.709563994374121
Threshold: 0.13

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.5321824464105791
AUROC: 0.7817822021946228
AUPRC: 0.5742435185780537
Sensitivity: 0.7164750957854407
Specificity: 0.7143183897529735
Threshold: 0.13

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0060.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.93it/s]
Loss: 0.6076722471043468
AUROC: 0.7840616752458942
AUPRC: 0.5733063674216481
Sensitivity: 0.7123519458544839
Specificity: 0.7285513361462729
Threshold: 0.11

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.95it/s]
Loss: 0.5533670227053344
AUROC: 0.7914986989071288
AUPRC: 0.5887531574574496
Sensitivity: 0.7273307790549169
Specificity: 0.7232387923147301
Threshold: 0.1

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0061.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.95it/s]
Loss: 0.5627675764262676
AUROC: 0.7808049005118979
AUPRC: 0.5698895284536979
Sensitivity: 0.7174280879864636
Specificity: 0.7264416315049227
Threshold: 0.17

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.90it/s]
Loss: 0.5092352979606197
AUROC: 0.7884745489408392
AUPRC: 0.5838369720998267
Sensitivity: 0.7254150702426565
Specificity: 0.7143183897529735
Threshold: 0.15

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0062.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.93it/s]
Loss: 0.643798628821969
AUROC: 0.771490310589456
AUPRC: 0.5560371942784144
Sensitivity: 0.7123519458544839
Specificity: 0.7081575246132208
Threshold: 0.09

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.95it/s]
Loss: 0.5847012874900653
AUROC: 0.7808958436304874
AUPRC: 0.5711014134952769
Sensitivity: 0.7126436781609196
Specificity: 0.720722781335773
Threshold: 0.09

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0063.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.94it/s]
Loss: 0.5974147217348218
AUROC: 0.779174728284797
AUPRC: 0.5662616709826535
Sensitivity: 0.727580372250423
Specificity: 0.7165963431786216
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.91it/s]
Loss: 0.538212840595553
AUROC: 0.7888258936761162
AUPRC: 0.5850634979360907
Sensitivity: 0.7151979565772669
Specificity: 0.7232387923147301
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0064.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.5973454872146249
AUROC: 0.7732585119978297
AUPRC: 0.5559453529440347
Sensitivity: 0.7191201353637902
Specificity: 0.7116736990154712
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.96it/s]
Loss: 0.5437393068305908
AUROC: 0.7830981200464117
AUPRC: 0.5744108539197346
Sensitivity: 0.7126436781609196
Specificity: 0.7307868252516011
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0065.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.97it/s]
Loss: 0.6615739427506924
AUROC: 0.7789415065647154
AUPRC: 0.5711169311769679
Sensitivity: 0.7225042301184433
Specificity: 0.7158931082981715
Threshold: 0.08

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.96it/s]
Loss: 0.5955443008933016
AUROC: 0.7896035844027767
AUPRC: 0.5880241489724459
Sensitivity: 0.7171136653895275
Specificity: 0.7319304666056725
Threshold: 0.08

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0066.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  5.00it/s]
Loss: 0.6479443199932575
AUROC: 0.7745888277276828
AUPRC: 0.5603611773843987
Sensitivity: 0.7106598984771574
Specificity: 0.7116736990154712
Threshold: 0.09

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.94it/s]
Loss: 0.585753551413936
AUROC: 0.7853654657117919
AUPRC: 0.5785509846693357
Sensitivity: 0.7068965517241379
Specificity: 0.7314730100640439
Threshold: 0.09

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0067.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.574729647487402
AUROC: 0.7766223783379858
AUPRC: 0.5627844996970194
Sensitivity: 0.7174280879864636
Specificity: 0.7130801687763713
Threshold: 0.15

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.98it/s]
Loss: 0.520478809552808
AUROC: 0.7859421793626923
AUPRC: 0.5784747685943898
Sensitivity: 0.7177522349936143
Specificity: 0.7305580969807868
Threshold: 0.15

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0068.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.99it/s]
Loss: 0.595527402125299
AUROC: 0.7758977251363038
AUPRC: 0.5634559176070313
Sensitivity: 0.7174280879864636
Specificity: 0.7123769338959213
Threshold: 0.13

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.99it/s]
Loss: 0.5367269362172773
AUROC: 0.7858342418198241
AUPRC: 0.5800746930204188
Sensitivity: 0.7286079182630907
Specificity: 0.7127172918572735
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0069.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.6333860289305449
AUROC: 0.7664129785507413
AUPRC: 0.5503407849574191
Sensitivity: 0.7123519458544839
Specificity: 0.7039381153305204
Threshold: 0.11

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.96it/s]
Loss: 0.5651385713649052
AUROC: 0.777688243658998
AUPRC: 0.5654483137570367
Sensitivity: 0.7049808429118773
Specificity: 0.7232387923147301
Threshold: 0.11

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0070.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.6448229886591434
AUROC: 0.77434370694025
AUPRC: 0.5573960805448057
Sensitivity: 0.7123519458544839
Specificity: 0.7208157524613221
Threshold: 0.1

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.98it/s]
Loss: 0.5720078978807696
AUROC: 0.7867071629631968
AUPRC: 0.5791298581449144
Sensitivity: 0.7273307790549169
Specificity: 0.717291857273559
Threshold: 0.09

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0071.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.96it/s]
Loss: 0.6146136941388249
AUROC: 0.7866687609025205
AUPRC: 0.5741633781791052
Sensitivity: 0.7157360406091371
Specificity: 0.7285513361462729
Threshold: 0.11

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.97it/s]
Loss: 0.551966874990412
AUROC: 0.795711184257419
AUPRC: 0.5937633711910184
Sensitivity: 0.7298850574712644
Specificity: 0.7321591948764867
Threshold: 0.1

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0072.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.98it/s]
Loss: 0.6116201682016253
AUROC: 0.7757680253021767
AUPRC: 0.5635253421130524
Sensitivity: 0.7208121827411168
Specificity: 0.7130801687763713
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.99it/s]
Loss: 0.5466638567947573
AUROC: 0.7868531488550733
AUPRC: 0.5806455141052895
Sensitivity: 0.7132822477650064
Specificity: 0.7303293687099726
Threshold: 0.12

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0073.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.99it/s]
Loss: 0.6143614165484905
AUROC: 0.7582597376017667
AUPRC: 0.5387487193012309
Sensitivity: 0.6971235194585449
Specificity: 0.7011251758087201
Threshold: 0.13

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.97it/s]
Loss: 0.5475761767036171
AUROC: 0.7731106110053645
AUPRC: 0.5581589163570575
Sensitivity: 0.7049808429118773
Specificity: 0.7188929551692589
Threshold: 0.13

Intermediate Model:
  ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0074.model
AUROC/AUPRC on Validation Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 32/32 [00:06<00:00,  4.95it/s]
Loss: 0.6139880362898111
AUROC: 0.7681645212648233
AUPRC: 0.5540897933504254
Sensitivity: 0.7174280879864636
Specificity: 0.7025316455696202
Threshold: 0.12

AUROC/AUPRC on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.91it/s]
Loss: 0.5464714488355062
AUROC: 0.7823491298977937
AUPRC: 0.5738507303124166
Sensitivity: 0.7203065134099617
Specificity: 0.7154620311070449
Threshold: 0.12


Plot AUROC/AUPRC for Each Intermediate Model
  Epoch with best Validation Loss:   24, 0.4822
  Epoch with best model Test AUROC:   4, 0.8366
AUROC/AUPRC Plots - Best Model Based on Validation Loss
  Epoch with best Validation Loss:   24, 0.4822
  Best Model Based on Validation Loss:
    ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0024.model

Generate Stats Based on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.95it/s]
Loss: 0.46309909272578453
AUROC: 0.8211523114116418
AUPRC: 0.6350720866597654
Sensitivity: 0.7413793103448276
Specificity: 0.7564043915827996
Threshold: 0.21
best_model_val_test_auroc: 0.8211523114116418
best_model_val_test_auprc: 0.6350720866597654

AUROC/AUPRC Plots - Best Model Based on Model AUROC
  Epoch with best model Test AUROC:   4, 0.8366
  Best Model Based on Model AUROC:
    ./vitaldb_cache/models/ABP_12_RESIDUAL_BLOCKS_64_BATCH_SIZE_0.0001_LEARNING_RATE_003_MINS__ALL_MAX_CASES_0004.model

Generate Stats Based on Test Data
100%|███████████████████████████████████████████████████████████████████████████████████████| 93/93 [00:18<00:00,  4.93it/s]
Loss: 0.6485231262381359
AUROC: 0.8365717517372248
AUPRC: 0.686771546895351
Sensitivity: 0.7401021711366539
Specificity: 0.7797346752058555
Threshold: 0.06
best_model_auroc_test_auroc: 0.8365717517372248
best_model_auroc_test_auprc: 0.686771546895351

Results (Planned results for Draft submission)¶

When we complete our experiments, we will build comparison tables that compare a set of measures for each experiment performed. The full set of experiments and measures are listed below.

Results from Final Rubrik¶

  • Table of results (no need to include additional experiments, but main reproducibility result should be included)
  • All claims should be supported by experiment results
  • Discuss with respect to the hypothesis and results from the original paper
  • Experiments beyond the original paper
    • Each experiment should include results and a discussion
  • Ablation Study.

Experiments¶

  • ABP only
  • ECG only
  • EEG only
  • ABP + ECG
  • ABP + EEG
  • ECG + EEG
  • ABP + ECG + EEG

Note: each experiment will be repeated with the following time-to-IOH-event durations:

  • 3 minutes
  • 5 minutes
  • 10 minutes
  • 15 minutes

Note: the above list of experiments will be performed if there is sufficient time and gpu capability to complete that before the submission deadline. Should we experience any constraints on this front, we will reduce our experimental coverage to the following 4 core experiments that are necessary to measure the hypotheses included at the head of this report:

  • ABP only @ 3 minutes
  • ABP + ECG @ 3 minutes
  • ABP + EEG @ 3 minutes
  • ABP + ECG + EEG @ 3 minutes

For additional details please review the "Planned Actions" in the Discussion section of this report.

Measures¶

  • AUROC
  • AUPRC
  • Sensitivity
  • Specificity
  • Threshold
  • Loss Shrinkage

[ TODO for final report - collect data for all measures listed above. ]

[ TODO for final report - generate ROC and PRC plots for each experiment ]

We are collecting a broad set of measures across each experiment in order to perform a comprehensive comparison of all measures listed across all comparable experiments executed in the original paper. However, our key experimental results will be focused on a subset of these results that address the main experiments defined at the beginning of this notebook.

The key experimental result measures will be as follows:

  • For 3 minutes ahead of the predicted IOH event:
    • compare AUROC and AUPRC for ABP only vs ABP+ECG
    • compare AUROC and AUPRC for ABP only vs ABP+EEG
    • compare AUROC and AUPRC for ABP only vs ABP+ECG+EEG

Model comparison¶

The following table is Table 3 from the original paper which presents the measured values for each signal combination across each of the four temporal predictive categories:

Area under the Receiver-operating Characteristic Curve, Area under the Precision-Recall Curve, Sensitivity, and Specificity of the model in predicting intraoperative hypotension

We have not yet completed the execution of the experiments necessary to determine our reproduced model performance in order determine whether our results are accurately representing those of the original paper. These details are expected to be included in the final report.

As of the draft submission, the reported evaluation measures of our model are too good to be true (all measures are 1.0). We suspect that there is data leakage in the dataset splitting process and will address this in time for the final report.

Discussion¶

Discussion (10) FROM FINAL RUBRIK¶

  • Implications of the experimental results, whether the original paper was reproducible, and if it wasn’t, what factors made it irreproducible
  • “What was easy”
  • “What was difficult”
  • Recommendations to the original authors or others who work in this area for improving reproducibility
  • (specific to our group) "I have communicated with Maciej during OH. The draft looks good and I would expect some explanations/analysis on the final report on why you get 1.0 as AUROC."
    • discuss our bug where we were believing we were sampling dozens of different patient samples but were just training the model on the same segments extracted from the same patient sample over and over. so we were massively overfitting our training data for one patient's data, then unwittingly using the same patient data for validation and testing, thus getting perfect classification during inference.

Feasibility of reproduction¶

Our assessment is that this paper will be reproducible. The outstanding risk is that each experiment can take up to 7 hours to run on hardware within the team (i.e., 7h to run ~70 epochs on a desktop with AMD Ryzen 7 3800X 8-core CPU w/ RTX 2070 SUPER GPU and 32GB RAM). There are a total of 28 experiments (7 different combinations of signal inputs, 4 different time horizons for each combination). Should our team find it not possible to complete the necessary experiments across all of the experiments represented in Table 3 of our selected paper, we will reduce the number of experiments to focus solely on the ones directly related to our hypotheses described in the beginning of this notebook (i.e., reduce the number of combinations of interest to 4: ABP alone, ABP+EEG, ABP+ECG, ABP+ECG+EEG). This will result in a new total of 16 experiments to run.

Planned ablations¶

Our proposal included a collection of potential ablations to be investigated:

  • Remove ResNet skip connection
  • Reduce # of residual blocks from 12 to 6
  • Reduce # of residual blocks from 12 to 1
  • Eliminate dropout from residual block
  • Max pooling configuration
    • smaller size/stride
    • eliminate max pooling

Given the amount of time required to conduct each experiment, our team intends to choose only a small number of ablations from this set. Further, we only intend to perform ablation analysis against the best performing signal combination and time horizon from the reproduction experiments. In order words, we intend to perform ablation analysis against the following training combinations, and only against the models trained with data measured 3 minutes prior to an IOH event:

  • ABP alone
  • ABP + ECG
  • ABP + EEG
  • ABP + ECG + EEG

Time and GPU resource permitting, we will complete a broader range of experiments. For additional details, please see the section below titled "Plans for next phase".

Nature of reproduced results¶

Our team intends to address the manner in which the experimental results align with the published results in the paper in the final submission of this report. The amount of time required to complete model training and result analysis during the preparation of the Draft notebook was not sufficient to complete a large number of experiments.

What was easy? What was difficult?¶

The difficult aspect of the preparation of this draft involved the data preprocessing.

  • First, the source data is unlabelled, so our team was responsible for implementing analysis methods for identifying positive (IOH event occurred) and negative (IOH event did not occur) by running a lookahead analysis of our input training set.
  • Second, the volume of raw data is in excess of 90GB. A non-trivial amount of compute was required to minify the input data to only include the data tracks of interest to our experiments (i.e., ABP, ECG, and EEG tracks).
  • Third, our team found it difficult to trace back to the definition of the jSQI signal quality index referenced in the paper. Multiple references through multiple papers needed to be traversed to understand which variant of the quality index
    • The only available source code related to the signal quality index as referenced by our paper in [5]. Source code was not directly linked from the paper, but the GitHub repository for the corresponding author for reference [5] did result in the identification of MATLAB source code for the signal quality index as described in the referenced paper. That code is available here: https://github.com/cliffordlab/PhysioNet-Cardiovascular-Signal-Toolbox/tree/master/Tools/BP_Tools
    • Our team had insufficient time to port this signal quality index to Python for use in our investigation, or to setup a MATLAB environment in which to assess our source data using the above MATLAB functions, but we expect to complete this as part of our final report.

Suggestions to paper author¶

The most notable suggestion would be to correct the hyperparameters published in Supplemental Table 1. Specifically, the output size for residual blocks 11 and 12 for the ECG and ABP data sets was 496x6. This is a typo, and should read 469x6. This typo became apparent when operating the size down operation within Residual Block 11 and recognizing the tensor dimensions were misaligned.

Additionally, more explicit references to the signal quality index assessment tools should be added. Our team could not find a reference to the MATLAB source code as described in reference [3], and had to manually discover the GitHub profile for the lab of the corresponding author of reference [3] in order to find MATLAB source that corresponded to the metrics described therein.

Plans for next phase¶

Our team plans to accomplish the following goals in service of preparing the Final Report:

  • Implement the jSQI filter to remove any training data with aberrent signal quality per the threshold defined in our original paper.
  • Execute the following experiments:
    • Measure predictive quality of the model trained solely with ABP data at 3 minutes prior to IOH events.
    • Measure predictive quality of the model trained with ABP+ECG data at 3 minutes prior to IOH events.
    • Measure predictive quality of the model trained with ABP+EEG data at 3 minutes prior to IOH events.
    • Measure predictive quality of the model trained with ABP+ECG+EEG data at 3 minutes prior to IOH events.
  • Gather our measures for these experiments and perform a comparison against the published results from our selected paper and determine whether or not we are succesfully reproducing the results outlined in the paper.
  • Ablation analysis:
    • Execute the following ablation experiments:
      • Repeat the four experiments described above while reducing the numnber of residual blocks in the model from 12 to 6.
  • Time- and/or GPU-resource permitting, we will complete the remaining 24 experiments as described in the paper:
    • Measure predictive quality of the model trained solely with ABP data at 5, 10, and 15 minutes prior to IOH events.
    • Measure predictive quality of the model trained with ABP+ECG data at 5, 10, and 15 minutes prior to IOH events.
    • Measure predictive quality of the model trained with ABP+EEG data at 5, 10, and 15 minutes prior to IOH events.
    • Measure predictive quality of the model trained with ABP+ECG+EEG data at 5, 10, and 15 minutes prior to IOH events.
    • Measure predictive quality of the model trained solely with ECG data at 3, 5, 10, and 15 minutes prior to IOH events.
    • Measure predictive quality of the model trained solely with EEG data at 3, 5, 10, and 15 minutes prior to IOH events.
    • Measure predictive quality of the model trained with ECG+EEG data at 3, 5, 10, and 15 minutes prior to IOH events.
    • Additional ablation experiments:
      • For the four core experiments (ABP, ABP+ECG, ABP+EEG, ABP+ECG+EEG each trained on event data occurring 3 minutes prior to IOH events), perform the following ablations:
        • Repeat experiment while eliminating dropout from every residual block
        • Repeat experiment while removing the skip connection from every residual block
        • Repeat the four experiments described above while reducing the numnber of residual blocks in the model from 12 to 1.

References¶

  1. Jo Y-Y, Jang J-H, Kwon J-m, Lee H-C, Jung C-W, Byun S, et al. “Predicting intraoperative hypotension using deep learning with waveforms of arterial blood pressure, electroencephalogram, and electrocardiogram: Retrospective study.” PLoS ONE, (2022) 17(8): e0272055 https://doi.org/10.1371/journal.pone.0272055
  2. Hatib, Feras, Zhongping J, Buddi S, Lee C, Settels J, Sibert K, Rhinehart J, Cannesson M “Machine-learning Algorithm to Predict Hypotension Based on High-fidelity Arterial Pressure Waveform Analysis” Anesthesiology (2018) 129:4 https://doi.org/10.1097/ALN.0000000000002300
  3. Bao, X., Kumar, S.S., Shah, N.J. et al. "AcumenTM hypotension prediction index guidance for prevention and treatment of hypotension in noncardiac surgery: a prospective, single-arm, multicenter trial." Perioperative Medicine (2024) 13:13 https://doi.org/10.1186/s13741-024-00369-9
  4. Lee, HC., Park, Y., Yoon, S.B. et al. VitalDB, a high-fidelity multi-parameter vital signs database in surgical patients. Sci Data 9, 279 (2022). https://doi.org/10.1038/s41597-022-01411-5
  5. Li Q., Mark R.G. & Clifford G.D. "Artificial arterial blood pressure artifact models and an evaluation of a robust blood pressure and heart rate estimator." BioMed Eng OnLine. (2009) 8:13. pmid:19586547 https://doi.org/10.1186/1475-925X-8-13
  6. Park H-J, "VitalDB Python Example Notebooks" GitHub Repository https://github.com/vitaldb/examples/blob/master/hypotension_art.ipynb

Public GitHub Repo (5)¶

  • Publish your code in a public repository on GitHub and attach the URL in the notebook.
  • Make sure your code is documented properly.
    • A README.md file describing the exact steps to run your code is required.
    • Check “ML Code Completeness Checklist” (https://github.com/paperswithcode/releasing-research-code)
    • Check “Best Practices for Reproducibility” (https://www.cs.mcgill.ca/~ksinha4/practices_for_reproducibility/)

Video Presentation (Requirements from Rubrik)¶

Walkthrough of the notebook, no need to make slides. We expect a well-timed, well-presented presentation. You should clearly explain what the original paper is about (what the general problem is, what the specific approach taken was, and what the results claimed were) and what you encountered when you attempted to reproduce the results. You should use the time given to you and not too much (or too little).

  • <= 4 mins
  • Explain the general problem clearly
  • Explain the specific approach taken in the paper clearly
  • Explain reproduction attempts clearly
In [99]:
print(f'All done!')
All done!